Путешествие веб-технологий началось в конце 80-х и начале 90-х годов, то есть уже более четверти века назад. За это время мы видели множество инноваций, конкурентов и продуктов, которые пытались доминировать в этом пространстве, борясь за невообразимое количество пользователей, ежедневно просматривающих веб-страницы.
Путь превращения браузера в инструмент, с которым пользователи могут взаимодействовать, имел множество форм. От зарождения JavaScript до появления Adobe Flash, SilverLight от Microsoft; очевидно, что интерактивность в браузере имеет достаточную полезность (и прибыльность), чтобы компании были готовы инвестировать в расширение возможностей.
В то время как первоначально веб был платформой для чтения документов. Инженеры нашли способы хитрого использования JavaScript для имитации более сложных настольных приложений. Благодаря таким методам, как скрытие/показ областей документа и динамическое заполнение разделов результатами, полученными от HTTP API, мы видим богатые приложения, написанные с помощью JavaScript. Примерами этого являются чат-клиенты, программы для управления бизнесом, текстовые процессоры и даже редакторы кода.
Когда вы задаетесь вопросом, почему эти сложные приложения, некоторые из которых в прошлом были приложениями для родной платформы, пишутся (или переписываются) как веб-приложения, вы часто приходите к вопросу о стоимости.
Идея "написать один раз и развернуть везде" действительно не является мемом, когда речь идет о веб-приложениях. Если на вашем устройстве есть современный веб-браузер, на нем можно запустить веб-приложение - все просто.
Проблема с веб-приложениями лежит в нескольких областях:
Поддерживаемость JavaScript в контексте сложных веб-приложений.
Функции, предоставляемые браузером; например, значимый доступ к файловой системе для сохранения данных или доступ к устройствам нижнего уровня.
Проблемы, связанные с "песочницей" динамически загружаемых скриптов и общей разрешительной моделью безопасности.
JavaScript в масштабе
Если вы написали крупномасштабное веб-приложение, вы, вероятно, знакомы со сложностью управления JavaScript в больших кодовых базах.
От идиосинкразии конфигураций баундеров, таких как Webpack, до соображений полифиллов, ориентации на наименее поддерживаемую версию браузера и управления/связывания зависимостей через npm для монорепо или проектов с несколькими репо.
Модули JavaScript определенно упростили синтаксический подход к созданию сопровождаемого кода, но большинство инженеров пишут большие проекты, используя такой язык, как TypeScript (хотя он и является надмножеством JavaScript, включение типов делает его совершенно другим в использовании).
Хотя TypeScript является одним из распространенных примеров, существует множество разновидностей компиляторов кода для JavaScript. CoffeeScript, Flow, Dart - первые, которые приходят на ум, но вы можете найти и транспиляторы, которые превращают Go или C в JavaScript.
Как ни странно, даже если вы пишете ванильный JavaScript сегодня, вы, скорее всего, все еще компилируете его из исходной формы в оптимизированную скомпилированную форму.
Здесь кроется проблема: JavaScript, который вы пишете, редко бывает тем JavaScript, который запускает браузер, а JavaScript не является оптимальной целью компилятора.
Если все, что мы пишем, все равно компилируется, разве не было бы здорово, если бы мы могли компилировать наши исходные языки до целевой формы, которая была бы меньше, быстрее и быстрее при первой загрузке?
Для решения этой проблемы была представлена Web Assembly.
Web Assembly - это низкоуровневый двоичный формат, который браузеры могут читать, что позволяет компиляторам языков нацеливаться на что-то более эффективное, чем JavaScript.
Естественно, инженеры перешли на территорию кликбейта и объявили о смерти JavaScript.
JavaScript сам по себе является очень популярным языком, а современный JavaScript фантастически эргономичен для небольших приложений. Так же, как и приложения, написанные на Python или PHP - это случается, и никто не умер.
Кроме того, было бы практически невозможно отказаться от интерпретатора JavaScript в браузерах, поскольку это сделало бы большую часть Интернета неработоспособной. С точки зрения логистики было бы практически невозможно заставить всех обновиться или сломаться.
Поэтому маловероятно, что JavaScript исчезнет. Если что, мы можем увидеть, что существующая поддержка JavaScript сохранится, пока язык JavaScript существует как спецификация языка, которую компиляторы используют для создания двоичных файлов Web Assembly.
По сути, представьте, что Babel конвертирует ваш JavaScript в двоичные файлы WASM вместо того, чтобы преобразовывать его в большее
Они будут иметь значок и наследовать родные украшения и элементы управления окон ОС.
К сожалению, на данном этапе установленные веб-приложения не имеют API для управления меню окон ОС (например, глобальным меню в MacOS или контекстным меню окна в Windows), но возможно, что такие возможности появятся в будущем.
Тот факт, что приложение установлено на вашем устройстве, не делает это приложение "прогрессивным". Предполагается, что "прогрессивное веб-приложение" устанавливает фоновый процесс, который запускается даже после закрытия приложения для управления такими задачами, как сетевое кэширование и получение push-уведомлений.
Ограничения, связанные с доступом к API ОС
По мере того, как веб-приложения начинают занимать место нативных приложений, становится очевидным, что ограничения API браузеров и отсутствие доступа к нижнему уровню ограничивают их возможности по замене нативных приложений.
Если представить себе такой пример, как Visual Studio code, широко используемый редактор кода. Невозможность получить доступ к файловой системе, управлять сетевыми портами или взаимодействовать с терминалами означает, что его невозможно распространять как чистое веб-приложение.
Как потребитель, вы не можете зайти на URL, например, https://visualstudiocode.app, установить приложение на свое устройство и начать им пользоваться.
Однако Visual Studio Code по-прежнему написан с использованием веб-технологий. Создатели просто включили пользовательский браузер с дополнительными API в дистрибутив.
Есть много примеров подобных приложений, которые требуют лучшего доступа к системным API, но не могут получить его от существующих браузеров, поэтому они упаковывают свой собственный браузер и распространяют его.
В итоге вы получаете несколько экземпляров форков Chromium/Webkit/Webview, адаптированных специально к требованиям приложений, в которые они обернуты.
Возможно, в будущем мы увидим, как браузер расширит возможности доступа веб-приложений, и мы начнем видеть мощные настольные приложения, распространяемые через Интернет с помощью домена .app.
Не бывает нативных приложений, если есть JavaScript
Еще одной распространенной жалобой на использование веб-технологий в нативных приложениях является использование JavaScript. Как мы знаем, большинство приложений на самом деле не используют JavaScript, они используют некую компиляцию кода в код, нацеленную на JavaScript (даже если источником является JavaScript).
Введение Web Assembly еще больше формализует поддержку любого языка программирования на веб-платформе и эту модель компиляции кода для выполнения в браузере.
Веб-ассемблер
Впервые о Web Assembly было объявлено в 2015 году, что делает ее очень новой технологией (забавный факт: она существует около 20% жизни веба).
Пока неясно, как будет выглядеть ее окончательная форма, но у нее есть большой потенциал для того, чтобы оказать значительное влияние на веб-мир.
Аргумент "нативный vs веб
Сразу скажем, что Web Assembly не решит всех проблем в споре между web и native. Однако она позволит большей части компаний и разработчиков приложений рассматривать веб-приложения, когда они думают о работе с родными устройствами - при условии, что системные API, открываемые из браузера, не являются ограничением.
Распространенная причина, по которой веб-приложения не являются предпочтительными, заключается в производительности. JavaScript, как мы знаем, является однопоточным языком. Вы можете использовать Web Workers, но они сложны в использовании и поэтому используются недостаточно.
Если говорить о нативных приложениях, не связанных с играми, будь то настольные или мобильные, то они обычно имеют поток пользовательского интерфейса, предназначенный для работы с пользовательским интерфейсом, а затем любое количество рабочих потоков для выполнения задач.
Это означает, что задачи, необходимые приложению, могут быть распределены по нескольким физическим ядрам CPU, а не привязаны к одному ядру.
Web Assembly, будучи низкоуровневым объектом компиляции для языков более высокого уровня, позволяет приложениям использовать потоки ОС.
Это означает, что инженеры могут писать веб-приложения на языках с лучшей поддержкой параллелизма (Rust, Go), а лучшее использование потоков приведет к более плавной работе для пользователей, а также обеспечит лучшую доступность для пользователей с более низким аппаратным обеспечением.
Однако Web Assembly не решит всех проблем с производительностью, поскольку некоторые нативные технологии имеют аппаратное ускорение (GPU-рендеринг) и в результате очень оптимизированы. С другой стороны, разумное использование CSS и растущий спрос на GPU-ускорение в Интернете приведут к тому, что со временем этот разрыв сократится.
Отсутствие функций Web Assembly сдерживает развитие
Недавно я прочитал статью, в которой отмечалось, что использование Rust в Web Assembly снижается.
Как инженер, который проводит большую часть своего времени за написанием веб-приложений, чувствительных к производительности, я отсчитываю секунды до того момента, когда я смогу использовать Rust в браузере, чтобы заменить использование TypeScript.
Я не могу говорить за всю отрасль, но лично меня сдерживает накладность кода JavaScript glue, которая является результатом отсутствия прямого доступа к веб-интерфейсам API. Я менее склонен рассматривать возможность переписывания своего приложения, если совокупный результат моего бинарного кода wasm + код клея будет такого же размера, как и мой пакет JavaScript.
Кроме того, очень трудно убедить мою команду в том, что преимущества производительности, которые дает эффективный язык с оптимизированным управлением памятью и параллелизмом, требуют от нас введения слоя отображения JavaScript API (glue code).
Учтите, что этот слой должен быть написан на TypeScript, покрыт модульными тестами, включать настройку компилятора для управления им в дополнение к недавно введенному второму языку с совершенно другим инструментарием.
Кроме того, оптимизация загрузки браузера, которую мы получаем с приложениями JavaScript, недоступна для двоичных файлов WASM, поскольку они не встраиваются в теги <script>, а вместо этого инстанцируются с помощью fetch в JavaScript. У браузера нет возможности предварительно получить и оптимизировать страницу, просматривая html, JavaScript должен быть разобран первым.
Прямой доступ к Web API будет предоставлен Web Assembly с предложением о типах интерфейсов, но никто не знает, когда мы увидим движение в этом направлении.
Мечта
HTML/CSS/WASM теперь больше похожи на набор для создания пользовательского интерфейса
Когда вы смотрите на фреймворки пользовательского интерфейса, вы найдете множество примеров реализаций для конкретных платформ и кроссплатформенных реализаций.
Windows имеет свои WinForms, WPF, Metro API. Apple имеет свои наборы пользовательского интерфейса на базе Swift. Linux будет использовать GTK, Android с его Java-реализацией, а iOS с собственной реализацией.
Вы смотрите на UI-фреймворки, пытающиеся преодолеть разрыв между платформами, и видите несколько претендентов. QT, Flutter, React Native и другие. В конечном счете, это просто своего рода фронт-энд, позволяющий вам писать логику на выбранном вами языке.
Вы можете написать приложение на QT, используя Go или Rust, и развернуть его на нескольких платформах. Однако вы упустите несколько платформ.
Веб движется в том направлении, где он, похоже, функционирует одинаково. HTML и CSS, хотя иногда и странные, являются выразительными и эффективными способами описания интерфейса приложения.
Привязка действий к выбранному вами языку с помощью Web Assembly означает, что за пределами определенных случаев использования не будет причин не использовать Web в качестве презентационного слоя для распространения вашего приложения.
Это позволяет инженерам обеспечить настоящую переносимость. Хотя все еще необходимо учитывать размер экрана, ничто не мешает интерпретировать эти приложения на любом устройстве с современным браузером.
Заключение
Направление, в котором медленно движется веб, указывает на то, что у него есть потенциал нарушить статус-кво нативных UI-фреймворков и нативных мобильных/настольных приложений.
Неясно, будет ли веб-консорциум продвигаться в этом направлении, но ясно, что это пространство, за которым нужно следить, с большим количеством инвестиций и полезности в инновации в этом направлении.
Как человек, который столкнулся с проблемой распространения нативных приложений на различных платформах (от Linux до iOS), я лично рад перспективе более мощных возможностей в браузере и думаю, что есть основания для оптимизма.
количество JavaScript.
Устанавливаемость приложений и PWA
Как многие из вас уже знают, веб-приложения могут быть установлены на устройство, если они отвечают определенным требованиям браузера.