Современное оборудование невероятно быстрое. M1 Max, на котором я пишу эту статью, работает с частотой 3,2 ГГц. То есть 3,2 МИЛЛИАРДА тактов в секунду. Однако Microsoft Teams требуется 3 секунды, чтобы открыть ссылку, и я отказываюсь верить, что для открытия ссылки требуется 9,6 МИЛЛИАРДА тактов. Очевидно, я упрощаю, но смысл остаётся прежним: как так получается, что оборудование становится быстрее, а приложения — только медленнее?
«Потому, что мы выполняем гораздо больше задач». Так считает любитель позднего капитализма. Позвольте объяснить.
Превосходный пример мощи современного «железа» — это видеоигры. Я могу симулировать огромные 3D-среды с физикой и освещением, полученным трассировкой лучей, при этом играть в реальном времени с друзьями из других штатов и даже стран; вполне доступный компьютер потребительского уровня выдаёт 124 миллионов пикселей в секунду1.
[1. 1080p при 60 FPS = 1920 × 1080 × 60 = 124416000]
Можно посмотреть и в обратном направлении: людям удаётся запускать DOOM на почти любом устройстве с процессором: на калькуляторах, iPod, фотокамерах. Невероятно маломощные, зачастую одноразовые устройства обладают достаточными вычислительными ресурсами, чтобы выполнять сверхсовременную на 1993 год игру. Это не особо удивляет, ведь прошло три десятка лет, но показывает, какой путь мы проделали.
«Веб плохой»
Веб крутой. На самом деле, веб настолько крут, что находится в собственном классе обратной совместимости, кроссплатформенности и доступности. Кроме того, у веба есть модель на основе событий, сильно упрощающая написание UI. Разумеется, за это удобство тоже приходится расплачиваться: скоростью. Выполнение настолько гибкого языка, как JS — само по себе сложная задача, и, вероятно, именно его вы в первую очередь будете винить, сравнивая быстрое нативное приложение с тормозной веб-версией. Конечно, интерпретируемый язык с динамической типизацией неизбежно требует больше памяти и работает медленнее.
В некоторых случаях JS заслуживает критики. Например, webpack должен парсить тысячи файлов, создавать AST и выполнять непонятные мне полностью сложные вещи, требующие больших ресурсов процессора, поэтому логично, что esbuild (Go) и swc (Rust) справляются с этим гораздо быстрее, чем webpack.
Однако в случае веб-приложений общего назначения это не так; веб — не причина того, что ваше великолепное приложение для IRC-чатов работает с частотой 5 FPS. Пару недель назад в Twitter вспоминали каталог сайта McMaster-Carr. Благодаря агрессивной предзагрузке и рендерингу на стороне сервера веб-сайт и навигация по нему работают невероятно быстро, несмотря на использование технологий, которым уже десятки лет (ASP.NET, jQuery). Любители всего нового посрамлены.
Если вы ненавидите React, то это может показаться отличным аргументом против React и других «современных» JS-фреймворков, но это совершенно2 неверный вывод. Зацените NextFaster (репозиторий) — столь же быстрая копия каталога McMaster, а то и превосходящая его по скорости, написанная на Next.js с хостингом на Vercel.
[2. Да, существует аргумент о «башне сложности» и бесконечные абстракции, которые мы создаём, чтобы просто выводить поля на экран, но этот аргумент не относится к производительности. Можно писать быстрые приложения практически на чём угодно.]
Вероятно, воплощением веб-технологий стала Figma. Если задуматься, то полнофункциональный дизайнерский инструмент, работающий в 60 FPS с «мультиплеером» в реальном времени — это просто безумие. Хотя, если честно, это не полностью JS, большая часть приложения работает на WebAssembly и WebGL. Могли они выжать ещё больше производительности из нативного приложения? Возможно. Но для этого пришлось бы отказаться от удобства веб-сайта, для работы с которым достаточно на него зайти. Вместо этого разработчики приложили все усилия к оптимизации и доказали, что браузер может демонстрировать настоящую мощь.
Примечание: огромная благодарность разработчикам V8, SpiderMonkey и JavaScriptCore за то, что всё это стало возможно. Именно благодаря вашему кропотливому труду мы вообще можем что-либо создавать.
«Electron плохой»
Примечание: здесь я подразумеваю сам Electron, CEF, WKWebView, Edge WebView2 и все остальные обёртки для превращения веб-приложений в нативные.
Electron позволил писать веб-приложения и преобразовывать их в десктопные приложения. Это несомненно привлекательная возможность. Теперь можно нанять разработчиков с одним набором навыков, написать один раз одно приложение и создавать «десктопные» приложения для каждой архитектуры и операционной системы (да, даже для Linux).
Чем же пришлось за это расплачиваться? Единственный надёжный способ запуска веб-приложений — через веб-браузер, поэтому в Electron просто… есть веб-браузер. Что может пойти не так? ¯\_(ツ)_/¯
Оказывается, многое. За последний десяток лет стало социально приемлемым то, что размер скачиваемых приложений превышает 500 МБ, а сами они требуют огромного количества ОЗУ и ресурсов CPU, при этом быстро разряжая аккумуляторы устройств. Но даже несмотря на высасываемые ими ресурсы, ими не так уж удобно пользоваться. Ненативность очень многих приложений «протекает» через странное поведение скроллинга и выделения, внешний вид и управление навигацией, не говоря уже об ужасной тормознутости при смене экранов. Discord и Teams — отличные примеры такой Electron-ификации. У них обоих есть отличные мобильные приложения, но десктопные — это просто переупакованный веб-сайт. Зачем?
Но винить в этом Electron будет не совсем справедливо. Electron просто сказал: «Есть способ поместить ваше веб-приложение в окно».
Настоящие виновники — компании, создающие эти приложения. Хорошие Electron-приложения создавать определённо можно, лучшие примеры — это Slack, Obsidian и Notion. Достаточно просто быть ответственными.
Посвящённый Electron раздел не был бы полным без упоминания Brackets, Atom и, главное, VS Code. Честно говоря, меня впечатляет, насколько хорошо работает VS Code, учитывая то, что редактирование больших файлов на JS похоже на стрельбу себе в ногу с последующим участием в марафоне: вы что-то докажете, но не совсем понятно, что.
Большая доля успеха VS Code, безусловно, связана с его экосистемой плагинов, и это не в последнюю очередь вызвано доступностью веб-стека. Недавно я написал плагин для SWC, и с уверенностью могу сказать, что степень удобства разработки (developer experience, DX) нативных плагинов и близко не стоит со сверхбыстрыми циклами итераций веба.
«Нативность плоха»
Мои пренебрежительные отзывы о веб-технологиях могут составить впечатление, что я люблю нативные приложения. Большинство нативных приложений замечательно в использовании (Postico, Zed), и я по возможности стараюсь пользоваться ими.
Перейдя пару месяцев назад на Zed, я уже не вернусь к VS Code. Всё в нём (действительно всё) происходит мгновенно. Вы можете думать, что VS Code и так «достаточно быстр», но это как сравнивать скорость звука со скоростью света. Разница едва ощущается, но в ней-то и весь смысл. Как Zed удалось этого добиться? Разработчики написали собственный GPU-фреймворк с нуля и создали редактор целиком на Rust. Когда используешь современное оборудование с умом, оно по-настоящему быстрое. Кто бы мог подумать?
Мне бы хотелось изучить глубже React Native для десктопов. Похожая на DOM модель рендеринга RN импонирует мне как веб-разработчику; к тому же мне кажется, что она обеспечивает нужный баланс между отличным DX и производительностью, особенно с New Architecture. Пока мне не очень понятно, почему RN для десктопов не особо популярен, ведь теоретически он выглядит как идеальный баланс (хотя причиной может быть недостаточно качественная поддержка со стороны разработчиков RN).
К сожалению, в мире нативности тоже не всё хорошо. Продукты Adobe славятся своими частыми вылетами. Меню поиска в Windows 11 смехотворно плохое. Activity Monitor в macOS требуется 5 секунд на составление списка работающих программ.
Так что же, мы обречены?
Очевидно, что эти проблемы не связаны с конкретным языком программирования, операционной системой или отраслью. Причина в более обширном тренде выпуска «быстрее и хуже». Скорость выпуска важнее, чем качество.
Трагедия общин
Ситуация особенно ухудшилась в последние годы, потому что современные компьютеры стали гораздо быстрее, чем требуется среднестатистическому человеку. Если начать прокручивать YouTube Shorts в десктопном браузере, то начнутся утечки ОЗУ (более 2 ГБ!) и наконец всё упрётся в ограничение ресурсов. Подобное было бы немыслимо в былые времена, когда у компьютеров было всего 2 ГБ ОЗУ. Кажущиеся неограниченными вычислительные ресурсы современных машин становятся оправданием для создания менее качественного ПО.
Уловка «приемлемости»
Как вы заметили, мне очень важно, чтобы программами было удобно пользоваться, но после общения с разными людьми я осознал, что такой подход не так уж популярен. Большинство людей устраивает, когда нужно ждать 500 мс появления контекстного меню после нажатия на правую клавишу мыши, и они не замечают торможений при изменении размеров окна. Это или привычка с тех времён, когда для загрузки изображения нужно было ждать 15 секунд, или выученная беспомощность перед плохим user experience. Но мы можем повысить качество, у нас есть технологии.
Культура «Ship It»
Можно создавать проекты, и создавать их быстро. Этой статьёй я не хочу обвинять кого-то в быстрых итерациях с новыми идеями, но существует огромная разница между тем, чтобы считать снижение производительности техническим долгом, и полным игнорированием производительности. Кажется, что во многих программах, которые мы используем каждый день, о производительности не задумывались даже после их выпуска; похоже, разработчики просто ждут, пока мощности оборудования догонят их потребности. Такой подход допустим, если вы создаёте что-то сверхпрогрессивное, но если ваша задача — вывести текст на экран, то я вряд ли с вами соглашусь.
Производительная производительность
Из прочтения этой статьи можно прийти к выводу, что я рекомендую оптимизировать всё вплоть до отдельных команд CPU. Хотя это само по себе было бы впечатляющим результатом, для большинства ПО это совершенно нереализуемо (если только вы не Крис Сойер, разрабатывающий RollerCoaster Tycoon). Эта статья не о производительности ради производительности. Просто я осознал, что разработчики крупномасштабного современного ПО, похоже, почти не заботятся об удобстве его использования, потому что вы всё равно будете им пользоваться. Не к такому будущему я стремлюсь.
Если вы разработчик ПО, то я призываю вас создавать его, стремясь к точности и качеству. Уделяйте внимание миллисекундам. Цените то, что вам нравится использовать. Держите планку своего ремесла и гордитесь им.
Хватит тратить большее на меньшие возможности.