[Перевод] Состояние WebAssembly – 2023 и 2024
Автор статьи Жерар Галлан известен как автор книги «WebAssembly in Action», выпущенной Manning в 2018 году. Существует перевод его книги на русский «WebAssembly в действии» (Питер, 2022). Предыдущий обзор Состояние WebAssembly в 2022–23 годах опубликован автором в январе 2023 года. — Прим. переводчика.
Добро пожаловать в 2024 год и в нашу статью о текущем состоянии WebAssembly (Wasm)!
В этой статье я займусь тем, что посмотрю, что произошло в 2023 году. Затем я выскажу свои мысли о том, что может произойти в текущем году.
Прежде чем начать, отмечу, что при обсуждении поддержки браузерами функций WebAssembly в этой статье я просто упоминаю, поддерживается ли эта возможность в Chrome, Firefox или Safari. Поскольку Edge создан на основе того же проекта Chromium с открытым исходным кодом, что и Chrome, он обычно наследует работу над WebAssembly. Поэтому, если функция WebAssembly поддерживается в Chrome, она обычно поддерживается и в Edge.
Тем не менее, если вы хотите проверить, поддерживается ли та или иная функция в вашем браузере, вы можете воспользоваться следующим сайтом. Если ваш браузер поддерживает функцию, то в колонке «Your browser» справа от её названия будет стоять галочка.
Обзор 2023 года
Прошедший год был невероятным для WebAssembly, и в нём было несколько сюрпризов, например, процесс «хвостовые вызовы» принял неожиданный оборот.
Хвостовые вызовы (Tail Calls)
Хвостовые вызовы полезны для оптимизации компиляции и некоторых форм потока управления, например, рекурсивных функций. Некоторые языки программирования также нуждаются в этой функции, чтобы использовать WebAssembly. Если вы хотите узнать больше о хвостовых вызовах, ознакомьтесь со следующей статьёй.
Хвостовые вызовы довольно долгое время находились под флагом в Chrome, и не могли быть выпущены, пока предложение не перешло в стадию стандартизации. В то же время, для того чтобы предложение было стандартизировано, необходимо, чтобы его реализовали как минимум в двух браузерных движках.
Когда я говорю о том, что что-то находится «под флагом», я имею в виду опции, которые пользователь может включить или выключить. В браузере это обычно делают разработчики, чтобы протестировать новые функции, которые ещё не готовы к повсеместному использованию. Будьте очень осторожны при настройке флагов, потому что они могут изменить работу браузера с некоторыми вещами. В некоторых случаях, поскольку функция может быть не до конца готова, могут возникнуть проблемы с безопасностью, которые ещё не решены.
В 2023 году казалось, что Safari станет вторым движком, в котором будут реализованы хвостовые вызовы, так как у них была реализация в Technology Preview 161, которая должна была выйти как часть Safari 16.4.
Поскольку казалось, что он вот-вот будет выпущен Safari, Chrome запланировал выход функции из-под флага. В то же время, группа сообщества WebAssembly проголосовала за перевод предложения в фазу 4 для стандартизации, поскольку два веб-движка должны были вот-вот начать работу с ним. К сожалению, были обнаружены проблемы с реализацией в Safari, и функция была отменена до выхода Safari 16.4. В результате, предложение было стандартизировано и выведено из-под флага в Chrome, но функция появилась только в одном веб-движке.
В декабре Firefox выпустил поддержку хвостовых вызовов, так что теперь у нас есть два веб-движка, которые её поддерживают. К сожалению, в Safari она по-прежнему недоступна.
Сборка мусора
В 2022 году предложение по сборке мусора быстро перешло на фазы 2 и 3 после того, как с 2017 года находилось на фазе 1. Я видел, что создатели браузеров много работали над этой функцией, и несколько языков также добавили её поддержку. В связи с этим я думал, что сборка мусора может быть выпущена в 2023 году, но я решил, что она будет выпущена под флагом для тестирования, и полностью мы увидим её только в 2024 году.
Я был приятно удивлён тем, что ошибся в своем прогнозе. Хотя, как я и ожидал, она был выпущена под флагом, она не была под флагом так долго, как я предполагал. На самом деле, она вышла из-под флага на версию раньше, чем планировалось в Chrome.
К октябрю и ноябрю 2023 года Chrome и Firefox выпустили поддержку сборки мусора.
Safari работает над сборкой мусора, но до завершения ещё далеко.
Если вам интересно узнать, как работает сборка мусора, то в следующей статье мы хорошо это объясним. Статья также содержит информацию о некоторых языках, в которых реализована её поддержка, таких как Kotlin, Dart и Flutter.
https://developer.chrome.com/blog/wasmgc
SIMD фиксированной ширины
SIMD (Single Instruction, Multiple Data) — это тип параллельной обработки, который использует преимущества SIMD-инструкций процессора для выполнения одной и той же операции над несколькими точками данных одновременно. Это может привести к значительному увеличению производительности при обработке изображений. Поскольку существует несколько типов SIMD, в качестве отправной точки были выбраны 128-разрядные SIMD-операции фиксированной ширины.
К середине 2021 года все основные браузеры, кроме Safari, поддерживали 128-разрядные SIMD-операции фиксированной ширины.
Safari был очень близок к тому, чтобы выпустить поддержку SIMD с фиксированной шириной к концу 2022 года, когда она была включена в Technology Preview 161.
В марте 2023 года Safari завершил поддержку этой функции в браузере, выпустив Safari 16.4.
Поддержка .NET 8 и платформы Uno для WebAssembly теперь включает поддержку SIMD по умолчанию, что позволяет ускорить выполнение векторных алгоритмов.
Если вам интересно узнать больше о SIMD с фиксированной шириной и о том, как использовать его в C#, мы написали об этом статью:
https://platform.uno/blog/safari-16–4-support-for-webassembly-fixed-width-simd-how-to-use-it-with-c
Множество блоков памяти
До этого момента модули могли иметь только один блок памяти. Если модулю требовалось взаимодействовать с JavaScript или другим модулем, используя его память, то был риск раскрыть информацию или случайно испортить её, если было разрешено прямое чтение и запись. Благодаря предложению Multiple Memories, модуль теперь может иметь несколько блоков памяти. Это открывает новые возможности, например, модуль может держать один блок для внутренних данных, а другой блок предоставлять для обмена информацией.
Я надеялся, что эта функция появится в 2022 году, но поскольку я не видел никаких движений со стороны создателей браузеров, я думал, что они решили, что это не достаточно приоритетная задача, поэтому я не ожидал её появления в 2023 году.
Chrome выпустил поддержку этой функции в конце года, в Firefox сейчас она находится под флагом.
Улучшения .NET в области WebAssembly
В каждом выпуске .NET часто добавляется или улучшается та или иная поддержка WebAssembly. Прошлый год не стал исключением с выходом .NET 8.
Поскольку код .NET использует управляемую память, ему требуется сборка мусора, а до недавнего времени в браузерах не было сборки мусора WebAssembly. Чтобы обойти это, в .NET используется среда исполнения mono, которая компилируется в WebAssembly и занимается сборкой мусора. Если ваше приложение .NET не скомпилировано AOT (Ahead of Time), ваш код интерпретируется в браузере средой исполнения .NET.
AOT-компиляция кода позволяет модулю WebAssembly работать быстрее и получить доступ к некоторым функциям, таким как SIMD. К сожалению, AOT-компиляция кода также обычно означает, что ваш модуль будет намного больше, поскольку в него необходимо включить код .NET, от которого он зависит. Увеличение размера файла приводит к задержкам при загрузке страницы, которые иногда становятся заметными.
В .NET 8 была найдена золотая середина, позволяющая быстрее загружать интерпретируемый код, но при этом быстрее его выполнять, поскольку была введена форма компиляции just-in-time (JIT) с помощью Jiterpreter. Теперь в процессе выполнения кода Jiterpreter может оптимизировать его, создавая код WebAssembly на лету, что приводит к повышению производительности при следующем запуске кода. Эта функция также доступна для приложений на платформе Uno.
Ещё одна проблема, связанная с запуском .NET Code в браузере, заключается в том, что до этого момента ваш код и поддерживающие его сборки загружались в виде файлов .dll. Эти файлы не выполнялись нативно, но загрузка .dll заставляла некоторых людей задуматься, а некоторые серверы блокировали возможность загрузки этих файлов в качестве меры предосторожности. В результате, в .NET 8 для файлов используется новый формат под названием WebCIL, в котором сборки .NET перепаковываются в файлы WebAssembly.
Hyperlight
В 2022 году в Docker и Kubernetes была добавлена экспериментальная поддержка WebAssembly, позволяющая использовать среду исполнения WebAssembly напрямую, а не в традиционной среде исполнения контейнера:
https://www.docker.com/blog/announcing-dockerwasm-technical-preview-2/
Прямое использование среды исполнения WebAssembly имеет ряд преимуществ, например, уменьшение размера контейнеров, поскольку для запуска модуля не нужны такие вещи, как библиотеки Linux или Node.js. С меньшим количеством библиотек и зависимостей контейнер становится более безопасным, так как уменьшается площадь атаки и меньше элементов, которые необходимо поддерживать в актуальном состоянии. Благодаря меньшему размеру время запуска контейнера увеличивается, и вы можете разместить больше контейнеров на одном устройстве. При желании вы можете использовать существующую инфраструктуру контейнеров для создания функций-как-услуг, и это позволит вам использовать ту же инфраструктуру, которую вы используете для своих обычных приложений, для обмена и распространения модулей WebAssembly.
На конференции Build 2023 компания Microsoft показала тизер того, над чем она работает, под названием Hyperlight. В следующем видео показано, как использовать гипервизор для запуска так называемых микро-виртуальных машин для запуска модулей WebAssembly.
Даже в таком коротком видеоролике интересно увидеть возможности по расширению набора мест, в которых могут работать модули WebAssembly.
WebAssembly System Interface (WASI)
WASI — это усилия по стандартизации, возглавляемые Bytecode Alliance, для использования WebAssembly вне браузера, чтобы обеспечить безопасное и стабильное выполнение задач. Это также включает создание набора интерфейсов, к которым могут обращаться ваши модули. Например, ваш модуль может использовать набор интерфейсов 'wasi-http' для отправки и получения HTTP-запросов.
WASI находится на уровне выше WebAssembly и использует разрабатываемую функцию под названием Component Model. Модель компонентов — это способ описания модуля, позволяющий связать вместе несколько модулей WebAssembly, написанных на разных языках программирования. Когда вы создаёте компонент, типы модуля описываются на высоком уровне. Это позволяет среде исполнения помогать модулям взаимодействовать на основе типов, указанных для импорта и экспорта. Если вам интересно узнать больше, на этом сайте вы найдете подробное объяснение компонентной модели и связанной с ней работы WASI.
Работа над WASI ведется поэтапно, и в настоящее время она находится на стадии Preview 1, но уже очень близка к выпуску Preview 2. Планируется выпустить Preview 3, а затем выпустить WASI 1.0. В следующем июльском обновлении объясняется, какие планы существуют для каждого этапа процесса выпуска.
Многие люди в восторге от возможностей WASI. Тем не менее, некоторые люди считают, что дело движется недостаточно быстро, поэтому они создали нечто под названием WASIX, которое располагается поверх WASI и предоставляет дополнительные возможности.
На первый взгляд WASIX напоминает мне TypeScript, сидящий поверх JavaScript. Я надеюсь, что дублирования стандартов не будет, и по мере доработки новых функций WASI, WASIX будет переходить на них.
Основное ограничение, которое я вижу в WASIX на данный момент, заключается в том, что он поддерживается только в среде исполнения Wasmer, в то время как WASI поддерживается в различных средах исполнения. Тем не менее, вы можете использовать Wasmer в довольно большом количестве мест. Посмотрим, как всё сложится, но если вы хотите узнать больше о WASIX, то можете заглянуть на следующий сайт.
Использование WebAssembly
Мне нравится, когда есть метрики, но я не знаю ни одной метрики использования WebAssembly вне браузера. Я могу судить об интересе к WebAssembly за пределами браузера только по разговорам, которые я вижу, количеству людей, рассказывающих о WebAssembly на конференциях, и анонсам продуктов. Судя по тому, что я вижу, за пределами браузера интерес к WebAssembly довольно высок.
В браузере мы имеем частичное представление об использовании WebAssembly. За последний год его использование увеличилось примерно на 1%, и теперь он используется чуть более чем на 3% сайтов, посещаемых пользователями Chrome. Это только Chrome, если учесть Safari, Edge и Firefox, то цифра будет выше. Учитывая размеры Интернета, 1% — это неплохой ежегодный прирост.
Упомянутые мной метрики использования веб‑сайтов можно найти здесь, если вам интересно (нажмите на флажок «Show all historical data»).
Учитывая, что 2023 год уже позади, чего мы можем ожидать в 2024 году?
Ожидания от 2024 года
Расширенные константные выражения
Расширенные константные выражения (Extended Constant Expressions) — это функция, которая больше относится к инструментальным средствам, чем к тому, что будет непосредственно использоваться обычным разработчиком. Это предложение призвано помочь в динамическом связывании модулей, добавив дополнительные инструкции для инициализации глобальных файлов и указания смещений таблиц или данных, которые не известны до времени исполнения.
Расширенные константные выражения теперь являются частью Safari Technology Preview 184, которая выйдет в декабре 2023 года. Я ожидаю, что Safari выпустит эту версию в ближайшие месяцы и тем самым завершит поддержку этой функции в браузере.
Сборка мусора
Safari упорно работает над реализацией сборки мусора. Судя по текущему списку тикетов и числу ещё открытых, работа завершена примерно на 75%. Трудно сказать, сколько времени займет работа над оставшимися тикетами, и будут ли добавлены другие в список. Ниже приведен зонтичный тикет, содержащий список всех тикетов по сборке мусора в Safari, которые они должны решить: https://bugs.webkit.org/show_bug.cgi? id=247394
Как только функция считается завершенной, она добавляется в Technology Preview, а затем в релиз, так что это занимает некоторое время.
Думаю, если Safari и выпустит её в этом году, то, скорее всего, это произойдет ближе к концу года.
Расслабленный SIMD (Relaxed SIMD)
Когда было предложено использовать SIMD в WebAssembly, в качестве отправной точки была выбрана 128-разрядная SIMD с фиксированной шириной, так как считалось, что она имеет наибольшую аппаратную поддержку.
Существуют другие SIMD-инструкции, которые могут быть использованы в зависимости от аппаратного обеспечения. Предложение Relaxed SIMD направлено на использование преимуществ некоторых из этих дополнительных инструкций. Если вы хотите узнать больше о Relaxed SIMD, предложение можно найти здесь.
Эта функция находится под флагом в Chrome и Firefox, но сейчас предложение находится на стадии стандартизации. Я ожидаю, что в скором времени эта функция появится под флагом в обоих браузерах.
Возможно, я ищу не там, где нужно, но я не вижу никакой активности со стороны Safari в отношении этой функции в настоящее время. Похоже, что команда Safari прилагает много усилий для реализации функции сборки мусора, так что, возможно, они просто с головой погрузились в эту работу и займутся остальным позже.
Множество блоков памяти
Предложение о множестве блоков памяти сейчас находится на стадии стандартизации. Судя по тому, что я вижу, эта функция появится под флагом в Firefox, но дата пока не опубликована. Я ожидаю, что она будет выпущена в этом году.
К сожалению, на данный момент я не вижу ничего от Safari по этому поводу.
Другие возможные функции, которые могут появиться в 2024 году
В Chrome и Firefox под флагами скрываются несколько функций, например Memory64 и Type Reflection. Эти два предложения всё ещё находятся в фазе 3, поэтому сначала они должны перейти в фазу 4, но если это произойдет, они могут быть выпущены уже в этом году.
Chrome работает над функцией интеграции промисов JavaScript (JavaScript Promise Integration). Они планируют добавить её в пробную версию Origin в конце января, начиная с версии 122 и вплоть до версии 130. Обычно, когда я вижу, что функция добавляется в пробную версию Origin, она сразу же становится доступной. Поскольку в Firefox эта функция также находится в процессе разработки, исходя из графика Chrome, я бы предположил, что она может появиться в Chrome и Firefox примерно в ноябре, если предложение будет переведено на этап стандартизации в то же время.
Как и в случае с Relaxed SIMD и множеством блоков памяти, я не вижу ничего от Safari вокруг Memory64, Type Reflection или JavaScript Promise Integration.
WebAssembly System Interface (WASI)
WASI Preview 2 должна выйти в начале 2024 года. Я не знаю, сколько времени потребуется на реализацию финальных функций, необходимых для выхода Preview 3. Несмотря на то, что Preview 3 будет считаться общедоступным релизом (GA release), похоже, что Preview 2 будет содержать достаточное количество функций, которые можно использовать для создания компонентов и экспериментов с WASI уже сейчас.
В следующей статье подробно рассказывается о планах Bytecode Alliance на 2024 год, если вы хотите копнуть глубже.
WASI с .NET
В .NET 7 была добавлена экспериментальная поддержка потоков WebAssembly, и она была запланирована к выпуску в .NET 8. К сожалению, в .NET 8 она не вышла из-под флага, но снова включена в список возможных вариантов для выпуска .NET 9 в ноябре.
Я бы хотел, чтобы .NET поддержал предложение по сборке мусора WebAssembly, но, похоже, на данный момент существует ряд проблем с его принятием, основанных на этой проблеме.
Даже без учета технических проблем, мы всё ещё ждем поддержки Safari, которая может появиться только в конце года. Без полной поддержки браузерами, как я подозреваю, команда .NET сосредоточится на других, более насущных проблемах.
Рабочая группа WebAssembly разработала пост-MVP план для сборки мусора, и команда .NET сообщила, что может внести свой вклад в эту спецификацию, пока они занимаются решением текущих технических проблем.
Когда-нибудь в .NET будет добавлена поддержка сборки мусора WebAssembly, но я не думаю, что это произойдёт в этом году.
Ещё одно интересное замечание: команда .NET экспериментировала с WASI для WebAssembly на стороне сервера и включила WASI Preview 1 в .NET 8. В .NET 9 они планируют включить поддержку WASI Preview 2. Ожидается, что работа над WASI будет оставаться экспериментальной до выхода WASI 1.0.
В этой статье подробно рассказывается об этих экспериментах, о том, как их использовать, и о результатах некоторых из них.
Стивен Сандерсон также продемонстрировал несколько различных способов использования WASI из .NET 8, если вы хотите ознакомиться с ними.
В заключение
2023 год стал ещё одним фантастическим годом для WebAssembly, в котором появилось несколько стандартизированных предложений, таких как хвостовые вызовы, сборка мусора, множество блоков памяти и расслабленный SIMD. Часть из этих функций уже реализована в некоторых браузерах и средах исполнения, работа над ними продолжается и в других браузерах.
Мы видим, как всё больше языков программирования, таких как Kotlin, Dart, Flutter и OCaml, добавляют поддержку WebAssembly, отчасти благодаря сборке мусора.
Поддержка инструментария продолжает совершенствоваться. В качестве примера можно привести .NET Jinterpereter, который динамически создаёт модули WebAssembly на лету, обеспечивая более быструю загрузку при использовании интерпретирующего подхода и быстрое выполнение при использовании подхода AOT. Благодаря WASI команда .NET также экспериментирует с запуском WebAssembly на сервере.
2024 год обещает стать ещё одним захватывающим годом для WebAssembly. Есть ощущение, что WebAssembly будет использоваться как в виде обычных модулей WebAssembly, так и компонентов WASI, особенно учитывая, что WASI Preview 2 будет выпущен довольно скоро.
Наконец, я слышал от многих людей, что WebAssembly очень хорошо подходит для работы с искусственным интеллектом. Мы уже видели некоторую работу в этом направлении: например, Google Meet использовала WebAssembly и машинное обучение для обработки размытия или замены фона при видеозвонках. Это было ещё в 2020 году, и с тех пор технологии усовершенствовались. Многие ожидают, что в этом году использование WebAssembly с искусственным интеллектом расширится.