Почему десктопные приложения работают на веб-платформе?

lfvgm9hdibt0hwuqceousqdffv4.png


Где мы свернули не туда? Как получилось, что современный десктопный GUI по умолчанию использует платформу HTML/CSS/JavaScript, которая изначально не предназначена для нативной работы на десктопе? Она создана конкретно для браузера и веба. Зачем из нативного софта делать веб-страницы в браузерной оболочке?

Джефф Этвуд (автор Stack Overflow) предсказал этот феномен ещё в 2007 году. Он тогда сформулировал так называемый закон Этвуда:

Любое приложение, которое можно написать на JavaScript, будет в итоге написано на JavaScript.


Так и вышло.
А если серьёзно, то это явный тренд в софтверной разработке, который наблюдается уже два десятилетия. Сейчас большинство GUI-приложений разрабатываются на платформе HTML/CSS/JavaScript.

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

В наше время на «Электроне» сделано практически всё:

  • 1Password
  • Asana
  • Discord
  • Figma
  • GitHub Desktop
  • Microsoft Teams
  • Skype
  • Slack
  • Trello
  • Twitch
  • Visual Studio Code (на скриншоте вверху)
  • WhatsApp


… и десятки других популярных десктопных программ.

Люди смирились и просто смотрят, как одна за другим нативные программы переходят на Electron со всеми вытекающими последствиями. Дело даже не в общей тормознутости и излишнем пожирании памяти (хотя это неизбежно в браузерной оболочке). В реальности производительность JS-кода по части UI даже обогнала типичный .NET за счёт многолетней тщательной оптимизации выполнения JS в браузерах. Нормально спроектированные JS-приложения сейчас гораздо быстрее, чем раньше. Но они по определению не могут сравниться с нативным софтом. Поэтому раздувание софта идёт полным ходом.

▍ Коммодитизация разработки


Почему так происходит? Логика абсолютно понятна. Фирме выгоднее разрабатывать и поддерживать одну платформу (веб) вместо N (веб+разные десктопные и мобильные ОС). Это чисто экономический вопрос: банально требуется меньше программистов.

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

JavaScript проще, чем C++, так что и с этой точки зрения веб-платформа кажется привлекательнее. Происходит своеобразная коммодитизация разработки, когда создание приложений ставится на конвейер. Все они становятся похожи друг на друга, и производятся в «фабричном» стиле с помощью фреймворков типа Angular JS и Vue.JS. Правда, со временем становятся видны недостатки такого подхода:

  • несовместимость разных версий фреймворков (приходится частично переписывать код);
  • браузеры, стандарты и экосистема HTML/CSS/JS слишком быстро изменяются (гораздо быстрее, чем это нужно для коммерческих приложений);
  • трудности в поддержке.


В итоге большие кодовые базы оказываются заблокированы в рамках определённой архитектуры/реализации. В некоторых ситуациях остаётся единственный вариант — переписать всё с нуля. С годами кодовая база начинает так пахнуть, что уже никто не хочет к ней прикасаться.

▍ Лучший консольный софт


Программисты старой школы не поддаются на новые веяния. Если посмотреть на творения лучших разработчиков, то там код максимально оптимизирован, GUI зачастую отсутствует, а производительность — наивысший приоритет. Вот список крутых опенсорсных программ, которые выбиваются из общего ряда. Это принципиально другой, «антипотребительский» подход к разработке. К сожалению, таких образцов становится всё меньше. Последние могикане. Упомянем некоторые из них:

▍ Аудиоплееры


  • moc — консольный аудиоплеер для Linux/UNIX
  • mpd — клиент-серверный плеер с консольным и графическим интерфейсом
  • mus — модульный демон/клиент с консольным интерфейсом, который принимает плейлисты в текстовом виде
  • vorbis-tools — плеер Ogg/FLAC


▍ Торрент-клиенты


  • btpd (The BitTorrent Protocol Daemon) — торрент-клиент, реализованный в виде демона


▍ RSS-ридеры


  • newsraft — фид-ридер с интерфейсом ncurses
  • sfeed — парсер RSS и Atom с интерфейсом sfeed_curses UI
  • snownews — текстовый RSS-ридер для Linux и Unix
  • zs — Zeitungsschau, конвертер RSS/email


▍ Файл-менеджеры


  • lf — файл-менеджер в стиле ranger, написанный на Go
  • mc — Midnight Commander, кросс-платформенный классический файл-менеджер
  • nnn — Nnn’s Not Noice, форк noice с большим количеством функций
  • noice — маленький и портативный файл-браузер
  • ranger — файл-менеджер с привязкой сочетаний клавиш на текстовый редактор vi, написанный на Python, с очень приятным интерфейсом
    2v2gjqvbsywjmmp8jqk89vydlby.png
    ranger
  • rover — простой консольный файл-браузер
  • sfm (simple file manager) — простой файл-менеджер для unix-подобных систем


▍ Git


  • stagit — генератор статических HTML-страниц для репозитория git
  • stagit-gopher — генератор страниц в формате .gph (gopher)
  • stagit-gemini — генератор страниц в формате .gmi (gemtext) для Gemini.


▍ Вьюеры картинок


  • feh — продвинутый вьюер с функцией установки обоев для рабочего стола
  • imv — простой вьюер X11/Wayland, зависимости: SDL2 и FreeImage
  • lel — простой вьюер для X11, читает изображения в формате Farbfeld
  • meh — вьюер, который напрямую использует XLib, libjpeg, libpng and libgif
  • qiv — Quick Image Viewer
  • sxiv — simple/small/suckless X Image Viewer, зависимости: xlib и imlib2. В данный момент осиротел (нет мейнтейнера)
  • nsxiv — Neo Simple X Image Viewer, форк осиротевшего sxiv, зависимости: xlib и imlib2
  • xli
  • xwallpaper — минималистичная утилита для обоев рабочего стола
  • xzgv


▍ Медиаплееры


  • ffplay — простой и портативный медиаплеер, поставляется с ffmpeg, которому нужен для работы mplayer
  • mplayer
  • mpv — свободный, кросс-платформенный медиаплеер


▍ Уведомления


  • herbe — уведомления без демонов и D-Bus. Минималистичный, легковесный, написан на C. Для вызова можно использовать tiramisu
  • tiramisu — демон уведомлений на базе dunst, который передаёт нотификации в STDOUT, так что пользователь может обрабатывать их на своё усмотрение, как в панели dwm


▍ Парольные менеджеры


  • oathtool — Open AuTHentication (OATH) для одноразовых паролей
  • pinentry-dmenu — программа для ввода паролей pinentry с добавлением динамических менюшек dmenu. Подходящий интерфейс для pass
  • pass — «стандартный парольный менеджер UNIX»
  • spm (simple password manager) — активно поддерживаемый форк tpm
  • tpm (tiny password manager)


▍ PDF-вьюеры


  • mupdf — легковесный PDF-вьюер, написанный на C. Поддерживает PDF, XPS, EPUB, XHTML, CBZ, PNG, JPEG, GIF и TIFF
  • zathura — расширяемый вьюер/оболочка, поддерживает CBZ, DJVU, PS, EPUB (с mupdf) и PDF (с mupdf или poppler)


▍ Оболочки


  • dash — POSIX-совместимая реализация /bin/sh, оптимизированная на минимально возможный размер
  • mksh (MirBSD Korn Shell) — активно разрабатываемая свободная реализация языка программирования оболочки Korn Shell, наследник Public Domain Korn Shell (pdksh)
  • oksh — портативная версия ksh из OpenBSD
  • yash (yet another shell) — задуман как POSIX-совместимая оболочка, которая в то же время поддерживает функции для ежедневного интерактивного и скриптового использования


▍ Текстовые редакторы


  • acme — текстовый редактор Роба Пайка для Plan 9. Включён в состав plan9port
  • ed — «стандартный текстовый редактор»
  • ired — минималистичный hex-редактор и биндиффер для p9, w32 и *nix
  • mg — портативная версия mg, поддерживается командой OpenBSD
  • mle — маленький, гибкий консольный текстовый редактор
  • nano — клон pico, маленький и простой в использовании
  • neatvi — минималистичная реализация vi с поддержкой двунаправленного UTF-8 (LTR/RTL)
  • nextvi — продолжение разработки neatvi с дополнительными функциями
  • nvi — маленький редактор в стиле vi
  • micro — консольный текстовый редактор со стандартными сочетаниями клавиш типа ctrl-c/v
  • sam — редактор от Роба Пайка, написанный под вдохновением от ed
  • sim — текстовый редактор на основе vim и sam
  • traditional vi — исправленная версия оригинального vi
  • vim (в GUI рекомендуется :set go+=c для блокировки всех всплывающих окон) может быть скомпилирован в предельно минималистичном стиле, как vim-tiny в репозиториях Debian
  • vis — современный и эффективный редактор в стиле vim
  • wily — клон acme для POSIX


▍ Обработка текста


  • csvquote — инструмент для кодирования проблемных символов CSV, чтобы unix-инструменты могли корректно их обрабатывать. Оптимизация SIMD по умолчанию, при сборке можно активировать откат на портативную версию C
  • json2tsv — конвертер из JSON в TAB-Separated Value (TSV) и отдельный JSON-парсер
  • md4c — конвертер из Markdown в HTML, быстрый, совместимый с CommonMark, поддерживает расширения, которые можно включать/отключать из консоли


▍ Утилиты/другое


  • abduco — подключение/отключение сессий
  • dvtm — динамический менеджер виртуальных терминалов
  • entr — запуск произвольных команд по факту изменения файлов
  • mrandr — простой и легковесный менеджер профилей мониторов (дисплеев), написанный на языке POSIX Shell
  • mtm (Micro Terminal Multiplexer) — мультиплексор консолей, на скриншоте внизу три инстанса tine
    oqxyt1owgf0azh7mpsl0mvqc8si.png

  • nq — утилита очереди командной строки UNIX
  • pv — инструмент для мониторинга прохождения данных по конвейеру
  • smenu — мощный и универсальный инструмент выделения в консоли для использования в интерактивном режиме или в скриптах
  • snore — пауза с визуальным фидбеком
  • yt-dlp — форк youtube-dl для скачивания видео и звука с YouTube и других платформ
  • zbar — пакет для распознавания штрихкодов из разных источников (видео, фото)


Полный список см. на сайте Stuff That Rocks.

▍ Оптимизация приложений. Примеры


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

Люди очень чувствительны к задержке интерфейса. Пятнадцать лет назад Amazon выяснила, что каждые 100 мс задержки веб-сайта уменьшают продажи на 1%. С тех пор требования публики значительно ужесточились.

В 2017 году Akamai констатировала, что каждые 100 мс задержки снижают конверсию уже на 7%.

В 2018 году Google опубликовала статистику по загрузке мобильных страниц. Выяснилось, что пользователи на мобильных устройствах менее терпимы к задержкам. Так, при росте задержки с одной до трёх секунд количество отказов от загрузки возрастает на 32%, при росте до пяти секунд количество отказов увеличивается на 90%, и так далее.

  • Рост задержки с 1 до 3 с → количество отказов возрастает на 32%
  • … с 1 до 5 с → на 90%
  • … до 6 с → на 106%
  • … до 10 с → на 123%


Поэтому так важно оптимизировать мобильные сайты и приложения. И есть стандартные способы оптимизации, доступные каждому. Например, разработчики DoorDash рассказали, как ускорили первоначальную загрузку iOS-приложения на 60%:

  1. Профилирование для выявления узких мест (они использовали Xcode, а также Performance Analysis от Emerge Tools).
    zgluvw2rhrz61dqv3vn5ejq8b8y.png
    Трассировка стека, показывающая три возможности оптимизации
  2. Исправление трёх основных проблем, на которые тратится время в основном потоке:
    • Проверка соответствия протоколу Swift — никто даже не знал, что стандартный String (describing:) занимается такими дорогими операциями.
      1cq6w6jdppv-xatjh5ji_lfcqpa.png
      Трассировка стека String (describing:) API

      Замена идентификации типов String(describing:) на простой указатель типа ObjectIdentifier сразу ускорила загрузку приложения на 11%, а это всего одна строчка кода!

      k7mvsfvz9f11zcnhdtm35wrfkva.png

    • Отказ от тотального хеширования AnyHashable абсолютно всех действий и команд для хранения их уникальных значений. Переосмысление архитектуры привело к пониманию, что необязательно идентифицировать все команды по их хешу, а зачастую достаточно просто указателя на тип.
      zk4tki5otxpapj_g07dsmnqih0y.png

      Эта простая оптимизация (опять одна строчка кода) ускорила запуск приложения ещё на 29%, а выполнение команд — на 55%.
    • Аудит инициализации сторонних фреймворков показал, что эти ненужные вызовы замедляют запуск приложения примерно на 200 мс (конкретно в этом случае виноват фреймворк ServiceCore от Salesforce).
      yf5c2d23saslhc3pd4ywrr6jye0.png

      Разработчики подкрутили динамический линкер (dyld), чтобы он пропускал эти вызовы при запуске.


Все сделанные оптимизации в целом ускорили запуск приложения DoorDash примерно на 60%.

Эта история наталкивает на мысль, что большинство мобильных приложений абсолютно не оптимизированы. Они включают в код внешние библиотеки, которые 90% времени выполняют ненужные операции, как String (describing:) выше, добавляя задержку на пустом месте.

В результате даже самая простая программа типа hello, world! с внешними модулями и зависимостями начинает неизбежно лагать на любом, даже самом быстром устройстве.

zyqdw7lijfhr3ancvw67hfa2sce.png


Есть мнение, что пользователям не нужен быстрый софт, потому что они якобы «ленивы и туповаты». Мол, пипл «схавает» всё, что дадут. Даже ужасной прилагой с задержкой десять секунд на каждое нажатие будет кто-то пользоваться. Люди привыкают к ужасу — и начинают считать его нормой. Однако адаптивный механизм психики — не оправдание для создания плохих продуктов.

Так или иначе, но фронтенд на HTML/CSS/JavaScript стал стандартом на всех платформах: и на десктопных, и на мобильных. Даже инструменты для разработчиков выпускаются в том же стиле. Например, Visual Studio Code на КДПВ — это браузер (Chromium) с сервером Node.js и файлами HTML/CSS, скомпилированными в исполняемый бинарник. Все переходят на веб-платформу. Ничего не поделаешь, таков путь.

Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх

© Habrahabr.ru