Скетч из статьи Лин Кларк «Создание и работа с модулями WebAssembly»
WebAssembly (Wasm) — это бинарный формат для безопасного и эффективного выполнения портативных программ в стековой виртуальной машине (в браузере или на сервере). Как и ASM.js, представляет собой низкоуровневый код. Есть ещё WAT — WebAssembly Text, человекочитаемая версия бинарного кода.
WebAssembly — не столько язык программирования, сколько цель компиляции, новый вид ассемблера, который работает близко к железу, принимая программы на C, C++, Rust и других привычных языках. При этом Wasm гораздо быстрее ASM.js и выполняет код в браузере почти как нативные программы под любой ОС.
Анатомия модуля WebAssembly. Программы называются модулями, потому что здесь нет разницы между программой и библиотекой, источник
Первая версия набора функций WebAssembly 1.0 одобрена консорциумом W3С, а некоторые стандартные фичи уже поставлены во все ведущие браузеры. Даже есть случаи масштабного рефакторинга на Wasm, после которого производительность сайта по некоторым параметрам возрастает в несколько раз.
Формат Wasm разработан для того, чтобы браузер мог как можно быстрее его разобрать. Например, вот время загрузки модулей Figma до и после оптимизации:
И код Wasm очень компактен, так что сетевая задержка тоже минимизируется до предела. Сравнение размера до и после оптимизации:
Такая разница в размере неудивительна, потому что синтаксис JavaScript был разработан для людей и содержит много избыточности и дополнительных правил, которые необходимо проверить перед выполнением.
До появления WebAssembly код C++ можно было выполнять в браузере путём кросс-компиляции на Asm.js. Это подмножество JavaScript, в котором можно использовать только числа (никаких строк, объектов и т. д.). Для C++ ничего больше не нужно, поскольку здесь всё является либо числом, либо указателем на число (а указатели — это тоже числа). Адресное пространство C++ — это просто гигантский массив чисел JavaScript, а указатели — просто индексы в этом массиве.
WebAssembly работает иначе, и поэтому здесь перед выполнением не нужно проверять код на ограничения JavaScript/Asm.js. В итоге бинарный код WebAssembly декодируется и выполняется иногда в 23 раза быстрее, чем соответствующий код asm.js.
Другие преимущества Wasm:
- Код C++ сильно оптимизируется компиляторами LLVM ещё до перевода в WebAssembly. Это значит, что браузер может напрямую транслировать его в нативный код, без всяких оптимизаций. В отличие от Wasm, обычный JS для быстродействия нужно оптимизировать на многих уровнях.
- Для браузеров не составляет труда кэшировать трансляцию модуля Wasm в нативный код. То есть при второй загрузке страница с этим модулем запускается практически мгновенно. Этого нельзя сказать об Asm.js, который смешивается с обычным JavaScript и требует сложной проверки, что он действительно соответствует требованиям.
- WebAssembly нативно поддерживает 64-битные целые. В JavaScript поддерживаются 64-битные флоаты (с плавающей запятой) и только 53-битные целые. 64-битные приходится эмулировать, что гораздо медленнее.
▍ Высокая производительность
Можно найти великолепные примеры высокой производительности веб-приложений. Например, форумный движок AsmBB, написанный полностью на WebAssembly, с интерфейсом FastCGI и базой SQLite для хранения зашифрованных данных. Целью разработки было создание максимально быстрого и лёгкого движка, при этом с современным UI. Насколько это получилось, можно оценить на asmbb.org.
Проект собран компилятором Flat Assembler (FASM). Размер движка около 65 КБ. За счёт минимального размера он всегда в самом быстром серверном кэше. Это уменьшает задержку, создавая ощущение высокой скорости. Разница заметна в том случае, если сеть и БД не являются узкими местами при обращении к серверу. В противном случае, конечно, всё равно, на чём написан сам движок. Тут происходит оптимизация конкретно CPU на сервере, ведь форумы с высокой посещаемостью на самом деле неслабо нагружают процессор. AsmBB запускается абсолютно на любом сервере x86, даже стареньком домашнем ПК. Возможно, это самый быстрый в мире форумный движок (такие бенчмарки ещё не попадались).
Инструкция по установке:
Или взять графический веб-редактор Figma, который в 2018 году осуществил масштабный рефакторинг, переписав ключевые части движка на Webasm. Это позволило в несколько раз ускорить ключевые операции. Например, загрузка документов ускорилась в три раза:
Эту оптимизацию пришлось проводить после того, как редактор Figma начали использовать корпоративные менеджеры для создания сверхсложных приложений. Например, дизайнеры из группы Fluent Design Team в Microsoft создали единый документ Figma со всеми элементами управления Windows во всех возможных состояниях и перестановках. По отдельности это несложные вычисления, но время загрузки такого документа оказалось существенным. Оптимизация на Webasm позволила сократить его с 29 до 8 с.
Чтобы понимать сложность обработки в редакторе, некоторые файлы Figma с сотнями тысяч слоёв с трудом умещаются в браузерный лимит оперативной памяти 2 ГБ для кучи. Из браузеров лимит 4 ГБ поддерживает только Chrome, да и то с багами.
На WebAssembly переписали все части, где происходит взаимодействие приложения с пользователями, включая десктопные версии, Chrome, Firefox и Safari на macOS и Windows.
Масштабирование тоже стало втрое быстрее:
Перетаскивание мышкой до и после оптимизации WebAssembly:
Если эти операции выполняются без лагов (фреймы максимальной длины в сотни миллисекунд), то в анимациях UI выпадает меньше кадров. Figma ориентируется на комфортный для пользователя фреймрейт 60 fps без лагов. К этому показателю приложение напрямую приблизилось после оптимизации WebAssembly:
Быстрый интерфейс — неотъемлемая часть удобного UX.
Для людей, которые устали от тормозных интерфейсов ожиревших сайтов и неповоротливых приложений, примеры использования WebAssembly с отзывчивым UI — словно глоток свежего воздуха в атмосфере современного веба.
Figma стала одним из пионеров по внедрению Wasm, потому что сооснователь и технический директор (ведущий программист) Figma Эван Уоллес был большим фанатом WebAssembly и опенсорса. Он выкладывал свои разработки на Github и многое сделал для продвижения этого революционного веб-стандарта (уволился в 2021-м).
Figma до сих пор остаётся примером не только коммерческого успеха, но и технического совершенства как программное приложение. Хотя сейчас появилось уже много последователей, веб-редакторов для быстрого прототипирования интерфейсов, таких как Penpot.
Penpot
▍ Изучение WebAsm на практике
Для интенсивного изучения WAT с глубоким погружением можно рекомендовать WATlings — это специальный курс обучения путём исправления маленьких программ. Опыт показывает, что новые навыки усваиваются максимально быстро, если сразу дать практические задания, то есть создать «препятствия», которые ученик будет самостоятельно преодолевать. Это самая эффективная методика.
Многое о языке можно узнать только из его синтаксиса. Возникающие пробелы в знаниях восполняются знакомством с синтаксисом в различных контекстах. То есть многие вещи усваиваются без всякого предварительного объяснения, а просто на практике.
Здесь ещё один наглядный пример того, что излишние объяснения не только затрудняют, но и замедляют понимание предмета. Бывает, что годичный курс теории вполне заменяется трёхмесячной практикой. Об этом методе подготовки много хороших отзывов, так что его стоит попробовать.
Похожий подход обучения программированию с помощью задач использует Exercism, а курс по WebAssemly включает 21 упражнение.
Exercism
Но там учиться сложнее. Придётся читать много теоретического материала, который даётся параллельно.
Другие примеры кода на WAT для изучения см. здесь.
▍ Будущее — за WebAssemly
Подводя итог, WebAssemly позволяет создавать в веб-приложения, которые по производительности не уступают нативным программам для настольных компьютеров. Это новая универсальная вычислительная платформа. Она уже доказала свои преимущества для C, C++, Rust и других языков, а теперь сообщество WebAsm готово к покорению мира. Игра началась.
P. S. Как мы уже говорили, многие функции WebAssembly 1.0 приняты и поддерживаются браузерами. В ближайшие месяцы ожидается внедрение в браузеры ключевой поддержки GC, после чего Wasm сможет ссылаться и обращаться к JavaScript, DOM и общим объектам, определяемым WebIDL. Также идёт разработка новых функций, входящих в набор следующего поколения WebAssembly 2.0.
Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх ????️
Комментарии (14)
event1
27.09.2023 09:07+5многое сделал для продвижения этого революционного веб-стандарта (уволился в 2021-м).
Уволиться — это конечно не мало. Не поспоришь.
Для людей, которые устали от тормозных интерфейсов ожиревших сайтов и неповоротливых приложений, примеры использования WebAssembly с отзывчивым UI — словно глоток свежего воздуха в атмосфере современного веба.
Подождите 24 месяца и всё вернётся обратно как было
Val_SA
27.09.2023 09:07А почему именно 24 месяца?
event1
27.09.2023 09:07+3Сначала примут новый стандарт. Потом его реализуют в браузерах. Потом добавят поддержку во всякие реакты, да ангуляры. Потом массово выкатят новые версии. Потом пользователи и (что важнее) всякие продуктологи и продаваны заметят, что всё стало работать быстрее. Потом продуктологи и продаваны решат расширить функционал. Ведь появились "лишние" ресурсы. Вот на всё это я бы отвёл 24 месяца. Возможно, я излишне оптимистичен
NNikolay
27.09.2023 09:07+1Вы излишне оптимистичный. Просто сейчас говнокод оптимизируют до некоего предела в 2-3 секунды, которые юзер терпит. Просто будут меньше оптимизировать раз и так уже за 3 секунды грузится.
VBKesha
27.09.2023 09:07А что нибудь поменялось за последние годы, или как и раньше, WebAsm позволяет выполнять по сути только расчеты, а вся связь с внешним миром чисто через JS браузера?
dpytaylo
27.09.2023 09:07По крайней мере, появились современные фреймворки, например такой как leptos, который позволяет скрыть все детали реализации(прослойку в виде js), и писать на том же расте с leptos так же как на js с реактом. По производительности получается примерно как обычный js, но пишешь на своем языке. Например, на том же leptos'е, уже можно с легкостью писать ssr full-stack приложения, смешивая серверную и клиентскую части сайта, просто вызывая функции. Экосистема связанная с WASM сейчас очень быстро развивается и в вебе, и в облачной инфраструктуре.
Regul
27.09.2023 09:07Здравствуйте!
**это бинарный формат для безопасного и эффективного выполнения портативных программ...
Чем обуславливается безопасность выполнения? Подскажите пожалуйста.
domix32
27.09.2023 09:07+1Всё окружение изолировано внутри вкладки браузера. А та в свою очередь обёрнута в свою собственную песочницу. Большинство известных CVE связаны с несанкцbонированным доступом к памяти, именно проблемы с этим и фиксит wasm. Есть конечно шанс, что рантайм с багами и можно выбежать из песочницы, но их довольно оперативно фиксят. А так изоляция получается даже лучше чем у докера.
SWATOPLUS
27.09.2023 09:07+1Половину статьи можно вырезать в 2023 году, нет смысла обсуждать asm.js, можно лишь упомянуть что такое было. Где сравнения с js, и нативом? Статья ради статьи.
kovserg
А где сравнение с нативным вариантом?
yrub
а что там сравнивать, его производительность на сколько я понимаю на уровне js, а работает несколько быстрее просто потому что все изначально скомпилировано. v8 компилирует весь код который идет в интерпретатор во время выполнения скрипта (а та же java для примера ждет 10-20к вызовов, чтобы не тратить больше времени на компиляцию, чем на выполнение редкого метода), скорее всего отсюда и разница (по большей части). так что толку от этих 2-3 раз когда оно все равно раз в 50 медленней чем нативный код... как по мне смысл webassembly это запуск изначально нативных программ в браузере кое как, чтобы пыхтел браузер клиента а не ваш сервер для создания например видео и т.д. Те оно дает возможность запускать в браузере то, чего в нем никогда не было, т.к. писалось на "c", а на js было в виде поделок, поделок одного человека как принято в мире фронта ;)