WebAssembly был анонсирован в 2015 году. Первой демонстрацией стала реализация игры Unity Angry Bots в Firefox, Google Chrome и Microsoft Edge. Спустя всего 4 года после анонса WebAssembly был признан официальным веб-стандартом и четвертым веб-языком после HTML, CSS и JavaScript, а на сегодняшний день его поддерживают 94% браузеров.
WebAssembly обеспечивает скорость исполнения в браузере, близкую к нативной, что позволяет переносить в интернет десктопные приложения (например, AutoCAD) и даже видеоигры (например, Doom 3).
Похоже, WebAssembly удалось привлечь к себе всеобщее внимание. Самое время поговорить о нем.
- Что не так с JavaScript?
- Что такое WebAssembly?
- Это просто новый язык программирования, как C и C++?
- Как работает WebAssembly?
- Станет ли WASM будущим веб-приложений?
Мы ответим на все эти вопросы и познакомим вас с WebAssembly. Его потенциал способен изменить привычные нам сайты до неузнаваемости!
Что не так с JavaScript?
JavaScript был разработан Бренданом Эйхом в 1995 году для браузера Netscape. Он давал возможность добавлять некоторые взаимодействия к статичным веб-страницам тех дней.
JavaScript — интерпретируемый язык программирования с динамической типизацией. Язык является динамически типизированным, если тип переменной проверяется во время выполнения. В чем же проблема с таким типом языка? Посмотрим, что будет, если объявить переменную в C++, который является статически типизированным языком.
int x = 5 ;
Компилятор определяет тип и место в памяти для x
. И все это укладывается в одну инструкцию. Однако для такого же присваивания в JavaScript движок должен каждый раз при выполнении программы проверять, является ли переменная целым числом, float или любым другим допустимым типом данных. Таким образом, каждая инструкция в JavaScript должна пройти через несколько проверок типов и преобразований, что замедляет ее выполнение.
Ниже показано, на что JavaScript тратит время в процессе выполнения кода.
А теперь посмотрим, на что тратит время WebAssembly.
В WebAssembly упрощен весь процесс компиляции, что делает его более быстрым по сравнению с JavaScript.
JavaScript не был разработан для высокопроизводительных приложений, требующих большой нагрузки от процессора.
Что такое WebAssembly?
Браузеры могут поддерживать только JavaScript. Но что если бы у нас был виртуальный микропроцессор, способный преобразовать любой язык высокого уровня в машинный код, который можно запускать на всех основных браузерах? Именно это и делает WebAssembly.
Ниже приведен пример суммирующей функции, написанной на C++ и преобразованной в WASM.
Схема VirtualProcessor, преобразующего код C++ в двоичный код, понятный браузеру.
Это просто новый язык программирования, как C и C++?
Нет, это не язык программирования. Это технология, которая преобразует код, написанный на каком-либо языке программирования, в машинный код, понятный браузеру.
WASM (аббревиатура от WebAssembly) был разработан как целевая платформа для компиляции других языков, позволяющая компилировать серверный код (например, код на C или C++) и выполнять его внутри браузера.
Как работает WebAssembly?
Что такое язык ассемблера (assembly language) и ассемблер (assembler)?
- Каждый процессор имеет свою архитектуру, например x86 или ARM. Кроме того, процессоры могут понимать только машинный код.
- Написание машинного кода утомительно, поэтому для данной архитектуры/процессора существует язык ассемблера.
- Ассемблер преобразует инструкции на языке ассемблера в машинный код, понятный процессору.
Вот как приложения, написанные на языке C, работают на компьютере.
В WebAssembly, как и в универсальном ассемблере, код, написанный на языке высокого уровня, таком как C++, преобразуется в машинный код, понятный браузеру.
Начало работы с WebAssembly
WebAssembly — это просто файл с расширением WASM. Его можно рассматривать как модуль, который может быть импортирован в JavaScript-программу.
Помните: WASM не может взаимодействовать с DOM напрямую. Поэтому вам нужно использовать как JavaScript, так и WASM.
Из вышеприведенного обсуждения следует, что вы можете запускать такие языки, как C и C++, в браузерах с почти нативной производительностью. Чтобы достичь этого, нужно выполнить следующие шаги.🖖
1. Напишите приложение на предпочитаемом языке
Напишем для примера небольшую функцию на C++, которая находит n-ое число Фибоначчи.
// Ниже приведена функция, написанная на C++, которая находит n-ое число Фибоначчи
int fib(int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
2. Создайте модуль WASM
Теперь нужно преобразовать файл C++ в предварительно скомпилированный WASM-модуль, который будет понятен браузеру.
Существуют различные способы преобразования кода на языке высокого уровня в WASM. В этом руководстве будет использован Web Assembly Explorer.
Шаг 1: скопируйте и вставьте код на C++ и кликните на компиляцию (compile).
Шаг 2: кликните на ассемблер (assembler).
Шаг 3: загрузите файл WASM.
Скопируйте и вставьте скачанный файл в каталог проекта под названием “math. wasm”.
3. Дистрибутируйте модуль — в идеале, используя CDN для низкой задержки (в данном случае будем запускать WASM-файл локально)
Создайте файл script.js
и пока оставьте его пустым.
Каталог проекта должен выглядеть следующим образом.
4. Загрузите модуль WASM
Мы создадим функцию loadWebAssembly()
, которая преобразует заданный файл в объект ArrayBuffer. Затем этот двоичный ArrayBuffer может быть преобразован в модуль WebAssembly. Необходимость создания объекта ArrayBuffer связана с памятью веб-ассемблера. Экземпляр этого модуля может быть прочитан браузером.
script.js
должен выглядеть следующим образом.
let math;
// Создадим функцию loadWebAssembly, которая преобразует данный файл в двоичный ArrayBuffer.
function loadWebAssembly(fileName) {
return fetch(fileName)
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer)) // Buffer converted to Web Assembly
.then(module => {return new WebAssembly.Instance(module) }); // Instance of Web assmebly module is returened
};
// Мы вызываем функцию для math.wasm для данного экземпляра.
loadWebAssembly('math.wasm')
.then(instance => {
});
5. Создайте экземпляр модуля
Теперь перейдем к самой сложной части — нам нужно ссылаться на функции, созданные на C++, в JS-файле. Но напрямую ссылаться на эти функции нельзя. Придется использовать имена, которые генерируются в файле WASM. Эти имена записаны в колонке WAT в Web Assembly Explorer.
Используйте имя функции, выделенное на следующей иллюстрации.
В вашем WAT-файле эти имена будут другими.
1-я часть в
script.js
посвящена загрузке файла WASM.
2-я часть содержит несколько простых функций Javascript, созданных для сравнения производительности Javascript и WebAssembly.
//---------------------------Часть 1--------------------------------------------------------
// Создадим функцию loadWebAssembly, которая преобразует данный файл в двоичный ArrayBuffer.
function loadWebAssembly(fileName) {
return fetch(fileName)
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {return new WebAssembly.Instance(module) });
};
// Вызываем функцию для math.wasm
loadWebAssembly('math.wasm')
.then(instance => {
fibc = instance.exports._Z3fibi;
console.log('Call your functions !');
});
//---------------------------PART 2 -----------------------------------------------
// Функция, написанная на Javascript, для числа Фибоначчи
function fibj(n)
{
if (n <= 1)
return n;
return fibj(n-1) + fibj(n-2);
}
// Эта функция дает время, необходимое для выполнения функции C++
function perfoc(n){
var startTime = performance.now()
var c=fibc(n)
var endTime = performance.now()
console.log(`Calculating nth Fibonacci with WASM took ${endTime - startTime} milliseconds,nth fibonacci is ${c}`)
}
// Эта функция дает время, необходимое для функции Javascript
function perfoj(n){
var startTime = performance.now()
var j=fibj(n)
var endTime = performance.now()
console.log(`Calculating nth Fibonacci with JS took ${endTime - startTime} milliseconds, nth fibonacci is ${j}`)
}
6. Вызовите функции экземпляра
Теперь для завершения работы загрузите сайт на localhost!
Примечание: вы не можете запустить index.html напрямую, так как он не загрузит модуль WASM. Используйте что-то вроде расширения Live Server в Visual Studio Code или Xampp, чтобы переместить каталог проекта на localhost.
Теперь перейдите в консоль, чтобы вызвать следующие две функции.
fibj( )
→ написана на простом Javascript.fibc( )
→ написана на C++ и затем преобразована в WebAssembly.
Ниже приводится сравнение между функцией fibj()
, написанной только на JavaScript, и функцией fibc()
, импортированной из WebAssembly.
Время выполнения fibj( )
и fibc( )
измеряется с помощью функций:
perfoj()
→ измеряет время выполненияfibj()
;perfoc()
→ измеряет время выполнения yfibc()
.
Как видно в приведенных выше GIF, время выполнения fibj()
(написанной на JavaScript) больше, чем время выполнения fibc()
(написанной с использованием WebAssembly).
Станет ли WebAssembly будущим веб-приложений?
С помощью WebAssembly можно разрабатывать высокоэффективные веб-приложения, которые будут работать с производительностью, близкой к нативной. WebAssembly позволит выполнять такие задачи, как обработка видео, 3D-рендеринг, мультимедийные игры, криптографические вычисления и live-приложения AR/VR.
Словом, для разработки любого приложения, требующей сложного написания кода и настроек производительности, WebAssembly является идеальным вариантом использования. Вы можете попробовать все сами!
Посмотреть проект можно здесь.
Читайте также:
- WebAssembly на Golang с нуля
- Как JavaScript повзрослел и стал настоящим языком
- Изучаем WebAssembly с помощью Rust
Читайте нас в Telegram, VK и Дзен
Перевод статьи Chandrashekhar Dongre: Introduction to WebAssembly (WASM)