Скетч из статьи Лин Кларк «Создание и работа с модулями 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.
Автор:
ru_vds