✦Разработка

Почему мы выбрали нативную разработку, а не Electron (и выбрали бы снова)

Все говорили нам: берите Electron. Пишете один раз — работает везде. Двигайтесь быстро. Мы сделали наоборот: SwiftUI на Apple, Jetpack Compose на Android, C++/WinRT на Windows, а там, где нужно успевать к каждому кадру, — чистые Metal и Vulkan. Вот что мы поняли, сделав четыре нативных клиента для одного продукта.

Легкий путь и правильный путь

Когда говоришь, что в 2024 году делаешь приложение удаленного рабочего стола с нуля, первый вопрос всегда один: «А почему не Electron?»

Вопрос справедливый. На Electron работают одни из самых успешных приложений в мире — VS Code, Slack, Discord, настольная оболочка Figma. Пишешь один раз и выпускаешь везде. Веб-разработчики за одну ночь становятся разработчиками десктопа. Выигрыш по времени выхода на рынок реален.

Мы посмотрели на цифры, взвесили компромиссы и выбрали самый трудный путь: полностью нативно на каждой платформе. SwiftUI на iOS и macOS. Jetpack Compose на Android. C++/WinRT на Windows. Metal для отрисовки на Apple. Vulkan на всем остальном. И собственный сервер на Go в основе.

Не потому, что нам нравится мучиться, хотя в иные дни так и кажется. А потому что для такого приложения нативность — не роскошь. Это требование.

«Налог Electron» реален

Начнем с того, чем Electron на самом деле является: окно браузера Chromium, которое притворяется настольным приложением. Это не упрек, а архитектура. Для многих приложений этого вполне достаточно.

Но для удаленного рабочего стола? Вы получаете пиксели с другого компьютера, выводите их в реальном времени, а заодно перехватываете каждое действие ввода и отправляете обратно. Задержка здесь — не приятное дополнение. Это весь продукт.

Вот что мы измерили, когда сделали прототипы обоих подходов:

380 МБ — это не раздутость Electron. Это Chromium делает свою работу: V8, графический процесс, вспомогательные процессы, целый движок браузера. Это впечатляющая инженерия. Просто она создана для другой задачи.

Кадры важнее функций

Удаленный рабочий стол — одна из немногих категорий приложений, где важен каждый кадр. Потерянный кадр человек чувствует. Добавьте 16 мс задержки ввода — и дизайнер не нарисует плавную кривую. Добавьте 32 мс — и геймер не сможет играть.

При нативной отрисовке мы напрямую обращаемся к GPU. На платформах Apple VideoToolbox дает прямой доступ к аппаратному декодированию видео. Мы берем кадр H.265 из сети, декодируем его аппаратно и показываем — кадр ни разу не попадает в основную память. Путь от декодирования до экрана занимает менее 4 мс на современном Mac.

В Electron тот же кадр проходит через композитор Chromium, через мост IPC, отрисовывается Skia, а потом еще раз компонуется операционной системой. Каждый шаг добавляет задержку. Каждый шаг добавляет джиттер. А джиттер — неровные интервалы между кадрами — и делает удаленный рабочий стол неприятным, даже когда средний FPS выглядит нормально.

Мы выбрали нативность не из пуризма. Мы выбрали ее, потому что этого требовала физика нашей задачи: около 8 мс обработки в локальной сети (остальное — собственная частота обновления вашего дисплея, 60 Гц) не оставляют места для браузера посередине.

Нативные и веб-возможности: сводка

Спор «Electron против нативного» часто тонет в ощущениях. Поэтому мы выписали семь возможностей ОС, на которые Remio опирается каждую секунду каждого сеанса, и прямо спросили: как каждая из них справляется в каждой среде?

ВозможностьНативноВеб / Electron
Аппаратное декодирование, 60 к/с● Напрямую через VideoToolbox / D3D11VA○ Через WebCodecs, джиттер
USB-аудио с малой задержкой● CoreAudio / WASAPI— Песочница, 40 мс и больше
Отслеживание ввода с клавиатуры● CGEvent / SendInput— Заблокировано вне фокуса
Доступ к GPU через Metal / D3D11● Текстуры без копирования○ WebGPU, лишние копирования
Локальная файловая система● Полный доступ в рамках, заданных ОС○ Только через диалог выбора, запросы
Несколько окон и дисплеев● Родное оконное управление ОС○ Прослойки BrowserWindow
Работа в фоне● LaunchAgent / служба— Приостановка при скрытии

Каждая строка — функция, которая у нас есть сегодня. Каждый прочерк в веб-столбце — обходной путь, который пришлось бы изобретать, документировать и за который пришлось бы извиняться. Нативная разработка позволяет нам считать эти возможности базовыми, а не полифилами.

Хороший гражданин платформы

Вот о чем редко говорят сторонники «написал один раз — запустил где угодно»: пользователи это чувствуют.

Они чувствуют, когда приложение не учитывает системные переходы между темной и светлой темой. Когда прокрутка ведет себя чуть-чуть не так. Когда приложения нет в Spotlight или оно неправильно работает с окнами macOS. Когда контекстное меню выглядит как веб-страница, а не как родное меню.

Это не приятные мелочи. Это разница между приложением, которое терпят, и приложением, которое любят. На iOS это особенно важно: проверка App Store отклонит приложение, которое выглядит чужеродным, и справедливо.

С SwiftUI все это мы получаем даром. Dynamic Type, доступность VoiceOver, системная тактильная отдача, многозадачность на iPad, сочетания клавиш на Mac. Мы не переизобретаем возможности платформы. Мы ими пользуемся.

Цена тоже реальна

Честно о минусах: нативная разработка дорога. Не в деньгах — во времени и сложности.

Мы поддерживаем четыре кодовые базы интерфейса. Сетевой слой и слой кодеков общие (Go для сигнализации, C++ для протокола стриминга), но каждый пиксель, который вы видите на экране, — это код под конкретную платформу. Функция, на которую в Electron уходит один день, у нас занимает от трех до пяти дней: мы делаем ее четыре раза, настраивая под каждую платформу.

Бывали недели, когда одна анимация прекрасно работала на iOS, была сломана на Android и подтормаживала на Windows. Матрица отладки получается жестокой.

Но вот что мы поняли: самый трудный путь и правильный путь часто совпадают. Пользователям неважна и неизвестна наша архитектура. Они знают, что Remio работает быстро, ощущается правильно и не съедает батарею на завтрак.

Сделали бы мы это снова

Без колебаний.

Нативный подход дал нам производительность, с которой Electron для этой задачи принципиально не сравнится. Он дал нам приложения, которые смотрятся родными на каждой платформе. Он дал нам менее 45 МБ памяти вместо 380 МБ. Он дал нам около 8 мс обработки в локальной сети (остальное — собственная частота обновления вашего дисплея, 60 Гц), тогда как конкурент в оболочке браузера уходит за 60 мс.

И самое главное — он дал нам технический ров. Делать нативные приложения сразу для четырех платформ настолько трудно, что большинство конкурентов за это не возьмется. Эта трудность и есть наше преимущество.

В категории удаленных рабочих столов долго господствовали веб-приложения в оболочке Electron и устаревшие нативные приложения, которые годами не получали серьезных обновлений. Есть место для чего-то одновременно современного и нативного — созданного с нуля с оглядкой на сегодняшнее железо.

Это Remio. Сделан трудным путем, потому что некоторые вещи стоит делать правильно.

Значок приложения Remio

Почувствуйте, что дает нативность

Remio бесплатен, нативен на каждой платформе и защищен сквозным шифрованием. Менее 45 МБ памяти, около 8 мс обработки в локальной сети (остальное — собственная частота обновления вашего дисплея, 60 Гц) — сделан трудным путем, чтобы ощущаться правильно.

Бесплатно100% нативноСквозное шифрование