Технологии в сфере разработки программного обеспечения развиваются стремительно. Появляются инструменты, которые помогают разработчикам создавать высокопроизводительные приложения, обеспечивающие пользователям хороший опыт. В разработке мобильных и веб-приложений первым и главным требованием является производительность. Это один из важнейших аспектов создания ПО, влияющий на формирование пользовательского опыта. Приложение может стать невостребованным только из-за задержек при выполнении пользователем определенных задач. Вторым важным требованием к качеству приложения является его безопасность. Отзывы пользователей о безопасности имеют не меньшее значение, чем производительность.
Как известно, браузер понимает только JavaScript. Независимо от того, какой фреймворк или библиотеку мы используем, вся информация сначала преобразуется в JavaScript, чтобы браузер идентифицировал ее и выполнил соответствующим образом. Из этого следует, что производительность веб-приложения в основном зависит от JavaScript. Является ли это проблемой?
В основном нет, за исключением некоторых случаев, связанных с динамическим поведением JavaScript. Для понимания динамического поведения углубимся в процесс выполнения JavaScript в движке браузера.
Почему JavaScript тормозит?
Каждый браузер имеет собственный JavaScript-движок. Например, Chrome использует движок V8, Mozilla Firefox — движок рендеринга Gecko и т. д. Это просто программа, выполняющая JavaScript-код. Каждый JS-движок состоит из двух компонентов:
- стек вызовов (в котором выполняется код);
- куча (неструктурированный пул памяти, в котором хранятся объекты).
Выполнение задач, ориентированных на использование процессора или аппаратного обеспечения, таких как кодирование JSON и декодирование некоторых криптографических данных, может занять у JavaScript много времени. Причиной тому является его динамическая природа, о которой говорилось выше. Сначала код парсится движком, затем преобразуется в код AST (Abstract syntax tree, абстрактное синтаксическое дерево), после чего отправляется в стек вызовов, где этот код исполняется (машинный код). Для экономии времени сначала отправляется неоптимизированная версия (байт-код), которая затем многократно возвращается обратно в компилятор TurboFan для получения оптимизированной версии, но выполнение кода не прекращается. Это замедляет работу JavaScript при выполнении задач, ориентированных на использование процессора или аппаратного обеспечения.

Для выполнения подобных операций используются языки низкого уровня, такие как C/C++, Rust и т. д. Они предоставляют ручное управление памятью и обеспечивают больший контроль над системным оборудованием. Эти языки преобразуются в машинный код, высоко оптимизированный и запускаемый непосредственно на аппаратном обеспечении. Но проблема низкоуровневых языков заключается в том, что, как упоминалось ранее, браузеры не допускают произвольного кода без какой-либо “песочницы” (изолированной среды) и идентифицируют только JavaScript, который находится в режиме “песочницы”. Так как же запустить программу в браузере, написанную на кроссплатформенном языке?
Как WebAssembly помогает сделать приложение более быстрым и безопасным?
Все самое интересное начинается с появлением WASM, обладающего мощью нативной веб-компиляции. Это язык программирования или целевой компилятор, преобразующий кроссплатформенные языки в язык WASM, понятный браузеру. Вы преобразуете файл “.c” или “.py” в файл “.s”, который является файлом сборки. При этом не нужно писать код непосредственно на языке WASM. Вместо этого вы используете подходящий вам кроссплатформенный язык, а WASM преобразует его в машинный код, чтобы браузер мог его понять и выполнить.
Причиной чрезвычайно высокой скорости WASM является небольшое количество этапов, которые он проходит перед выполнением. Если в JavaScript код сначала парсится, затем преобразуется в AST, отправляется на оптимизацию и только потом выполняется, то в WASM он непосредственно декодируется, затем компилируется, одновременно оптимизируясь, и выполняется.

Поскольку модуль WebAssembly (WASM) выполняется в “песочнице”, обеспечивающей высокий уровень безопасности, он не использует эксплойты на уровне операционной системы. Код выполняется в той же “песочнице”, которую браузер предоставляет JavaScript, и именно поэтому ему разрешено запускаться в браузере. Кроме того, в отличие от JavaScript, не нужно ждать полной загрузки полезных данных JSON перед парсингом. Если имеется WASM-файл, например, размером 5 МБ, то по мере загрузки его фрагментов они преобразуются в машинный код и выполняются, что делает WASM сверхбыстрым.
Пример: FFmpeg — бесплатное программное обеспечение с открытым исходным кодом, состоящее из библиотек для обработки аудио-, видео- и других мультимедийных файлов. Интересно то, что эта программа, выполненная на языке C++, является высокооптимизированной и работает в браузере с помощью WASM. Этот факт объясняется тем, что FFmpeg сначала был преобразован в двоичный формат WASM, чтобы браузер мог его понять.
Заменит ли WASM JavaScript?
После раскрытия возможностей WebAssembly (WASM) этот вопрос, конечно же, встанет перед вами. Но ответ на него: нет.

WASM не предназначен не для конкурирования, а для сотрудничества с JavaScript.

В конечном итоге произойдет следующее: вы будете писать JavaScript-код и вызывать функции WASM там, где это необходимо. Задачи, связанные с использованием процессора, будут выполняться в WASM, а DOM или операции, ориентированные на веб-фронтенд, такие как работа с сетью, отправка HTTP-запросов и т. д., будут по-прежнему выполняться в JavaScript. Это означает, что с помощью WASM нельзя выполнять задачи обновления пользовательского интерфейса. Для этого по-прежнему необходим JavaScript.
Заключение
Подводя итоги, можно сказать, что WASM — это язык программирования, который выполняется в “песочнице”, что делает его пригодным для работы в браузере. Для выполнения задач, связанных с использованием процессора, JavaScript не подходит из-за своего динамического поведения. Для таких целей применяются языки, позволяющие осуществлять больший контроль над аппаратным обеспечением (C/C++, Rust и др.).
Но эти языки не выполняются в “песочнице”, и поэтому их нельзя запускать в браузере. Чтобы запустить код, написанный на кроссплатформенном языке, конвертируйте файлы в WASM-файл, а затем запускайте их в браузере. Замечательно то, что в браузере вы получите скорость, близкую к нативной.
Поскольку WASM выполняется в той же “песочнице”, которую браузер предоставляет для JavaScript, то проблем с безопасностью не возникает. Благодаря гарантированной производительности и безопасности, WASM становится все более популярным и используется различными технологическими компаниями в мире.
Читайте также:
- Возможности и перспективы WebAssembly
- Движки JavaScript. Часть 1: парсинг
- WebAssembly на Golang с нуля
Читайте нас в Telegram, VK и Дзен
Перевод статьи Rabah Ali Shah: WebAssembly (WASM): A Secret Guide to Building Highly Optimized and Secured Web Applications