WebAssembly, часто называемый сокращенно Wasm, представляет собой новый рубеж в веб-разработке. Первоначально задуманный как средство запуска в браузерах языков, отличных от JavaScript, на скорости, близкой к исходной, он быстро становится выбором веб-разработчиков, которым нужен код, критичный к производительности, без ущерба для гибкости.

Одним из языков, добившихся значительных успехов на арене WebAssembly, является Go. Благодаря своим высоким характеристикам производительности и простому синтаксису Go (или Golang) естественно подходит для среды Wasm. В этой статье мы рассмотрим, как Go можно использовать для создания приложений, ориентированных на WebAssembly, позволяя использовать возможности Go прямо в вашем браузере и за его пределами.

1. Что такое WebAssembly (Wasm)?

WebAssembly — это двоичный формат инструкций, который позволяет запускать в браузере код, написанный на языках, отличных от JavaScript. Он действует как виртуальная машина и предоставляет компактный двоичный формат, который выполняется со скоростью, близкой к исходной. Благодаря своей конструкции он очень безопасен и эффективен, что делает его идеальным для задач, требующих высокой производительности.

2. Распространение Go в WebAssembly

Простота, эффективность и мощная стандартная библиотека Go делают его фантастическим кандидатом на замену Wasm. Команда Go осознала этот потенциал и, начиная с версии 1.11, включила экспериментальную поддержку компиляции программ Go в WebAssembly.

3. Написание вашей первой программы Go WebAssembly

Настраивать:

Сначала убедитесь, что вы используете Go версии 1.11 или новее. Затем установите переменные среды GOOS и GOARCH для целевого WebAssembly:

$ GOOS=js GOARCH=wasm go build -o main.wasm main.go

Простое приложение Go:

Напишите базовое приложение Go:

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello from WebAssembly!")
}

После компиляции вы получите файл main.wasm, который представляет собой ваш код Go, скомпилированный в WebAssembly.

Вставить в HTML:

Вам также понадобится файл wasm_exec.js, предоставленный Go, который служит мостом между Go и JavaScript:

$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

Затем ваш HTML-файл сможет загрузить и выполнить код WebAssembly:

<script src="wasm_exec.js"></script>
<script>
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => {
        go.run(result.instance);
    });
</script>

Загрузите этот HTML-код в свой браузер, откройте консоль, и вы должны увидеть сообщение Hello from WebAssembly!.

4. Вызов функций Go из JavaScript

Go WebAssembly также предоставляет возможность предоставлять функции, которые можно вызывать непосредственно из JavaScript:

package main

import (
    "syscall/js"
)

func add(i []js.Value) {
    js.Global().Set("output", js.ValueOf(i[0].Int()+i[1].Int()))
}

func registerCallbacks() {
    js.Global().Set("addNumbers", js.NewCallback(add))
}

func main() {
    c := make(chan struct{}, 0)
    registerCallbacks()
    <-c
}

После компиляции вы можете использовать функцию addNumbers в JavaScript:

addNumbers(5, 7);
console.log(output);  // Outputs: 12

5. Преимущества использования Go с WebAssembly

  • Производительность. Эффективность Go в сочетании со скоростью WebAssembly приводит к созданию высокопроизводительных веб-приложений.
  • Параллелизм: используйте горутины Go для параллельных задач в WebAssembly.
  • Стандартная библиотека: доступ к богатой стандартной библиотеке, упрощающей написание сложных приложений.

6. Ограничения и соображения

Хотя поддержка WebAssembly в Go многообещающа, она не лишена ограничений:

  • Размер: двоичные файлы Go WebAssembly могут быть большими, что может повлиять на время загрузки.
  • Управление памятью. В настоящее время в WebAssembly отсутствует сбор мусора.

Заключение

WebAssembly меняет наше представление о веб-приложениях, предлагая производительность и гибкость, которые ранее были недостижимы. Согласование Go с WebAssembly обещает новую волну веб-приложений, которые будут не только быстрыми, но также эффективными и надежными. По мере развития экосистемы разработчикам следует внимательно следить за захватывающими возможностями, которые может предоставить этот дуэт.