WebAssembly и Swift: Мощный тандем для веб-разработки

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Зачем Swift в браузере?

Мир веб-разработки переживает ренессанс. Долгое время JavaScript был безальтернативным королём фронтенда. Но что, если я скажу вам, что теперь вы можете запускать нативный, быстрый код Swift прямо в браузере, получая прирост производительности до 10-15 раз на сложных вычислениях? Звучит как фантастика? Добро пожаловать в эру WebAssembly (Wasm) и Swift.

В этой статье мы разберем, что такое WebAssembly, как он дружит со Swift, зачем это нужно обычному разработчику и как написать свой первый модуль на Swift, который будет работать быстрее, чем аналогичный код на JS. Если вы пишете на Swift под iOS/macOS или просто хотите расширить кругозор — этот материал для вас.

Что такое WebAssembly простыми словами?

Представьте, что браузер — это операционная система. JavaScript — это её родной, но не самый быстрый язык. WebAssembly — это бинарный формат инструкций (как машинный код), который браузер выполняет почти со скоростью нативного приложения. Вы компилируете свой код на C, C++, Rust или Swift в компактный .wasm-файл, и браузер запускает его в специальной виртуальной машине.

Ключевые особенности Wasm:

  • Скорость: Загрузка и выполнение в разы быстрее JS для тяжелых задач (шифрование, рендеринг 3D, обработка видео).
  • Безопасность: Код выполняется в изолированной песочнице, не имеет доступа к системе напрямую.
  • Переносимость: Работает во всех современных браузерах (Chrome, Firefox, Safari, Edge).

Swift + WebAssembly: Брак по расчету

Долгое время Swift считался языком исключительно для экосистемы Apple. Но проект SwiftWasm (и его фреймворк Tokamak для UI) перевернул эту парадигму. Теперь вы можете писать бэкенд, фронтенд и мобильные приложения на одном языке.

Почему именно Swift для Wasm?

  • Производительность: Swift компилируется в LLVM IR, который легко транслируется в Wasm. Код получается компактным и быстрым.
  • Безопасность памяти: ARC (Automatic Reference Counting) и строгая типизация уменьшают количество багов по сравнению с C++.
  • Синтаксис: Лаконичный и выразительный — писать на Swift одно удовольствие.
  • Современность: SwiftUI-like подход (через Tokamak) позволяет создавать реактивные интерфейсы прямо в браузере.

Главный минус: пока экосистема библиотек для SwiftWasm меньше, чем для Rust или AssemblyScript. Но для большинства задач — хватает.

Практика: Компилируем Swift в Wasm

Давайте напишем простой модуль, который будет вычислять числа Фибоначчи. Сначала на JavaScript, потом на Swift. Вы увидите разницу в скорости.

Шаг 1. Установка инструментов

Вам понадобится:

  • Swift 5.9+ (с поддержкой Wasm). Скачайте с swift.org.
  • SwiftWasm toolchain — специальная версия компилятора.
  • Node.js (для запуска примера в терминале).

Установка toolchain (пример для macOS):

brew install swiftwasm/tap/swiftwasm
swiftwasm --version

После установки создадим новый проект:

mkdir SwiftWasmDemo && cd SwiftWasmDemo
swift package init --type executable

Шаг 2. Пишем код на Swift

Откройте файл Sources/SwiftWasmDemo/main.swift и вставьте следующий код:

import JavaScriptKit

// Функция для вычисления чисел Фибоначчи (рекурсивно с мемоизацией)
func fibonacci(_ n: Int) -> Int {
    var cache = [Int: Int]()
    func fib(_ n: Int) -> Int {
        if let cached = cache[n] { return cached }
        if n <= 1 { return n }
        let result = fib(n - 1) + fib(n - 2)
        cache[n] = result
        return result
    }
    return fib(n)
}

// Экспортируем функцию в JavaScript
let jsFib = JSClosure { (args: [JSValue]) -> JSValue in
    guard let n = args.first?.number else { return .number(0) }
    let result = fibonacci(Int(n))
    return .number(Double(result))
}

// Регистрируем функцию в глобальной области видимости JS
_ = JSObject.global.setProperty("swiftFib", jsFib)

print("Swift модуль загружен! Используйте swiftFib(n) в консоли браузера.")

Важно: Мы используем библиотеку JavaScriptKit для взаимодействия с JS. Добавьте её в Package.swift:

// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "SwiftWasmDemo",
    dependencies: [
        .package(url: "https://github.com/swiftwasm/JavaScriptKit.git", from: "0.18.0")
    ],
    targets: [
        .executableTarget(
            name: "SwiftWasmDemo",
            dependencies: ["JavaScriptKit"])
    ]
)

Шаг 3. Компиляция в Wasm

Выполните команду:

swift build --triple wasm32-unknown-wasi

После успешной сборки вы найдёте SwiftWasmDemo.wasm в папке .build/wasm32-unknown-wasi/release/.

Шаг 4. Запускаем в браузере

Создайте HTML-файл index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Swift + WebAssembly Demo</title>
</head>
<body>
    <h2>Вычисление Фибоначчи</h2>
    <input type="number" id="input" value="40">
    <button onclick="runSwift()">Swift Wasm</button>
    <button onclick="runJS()">JavaScript</button>
    <p>Результат: <span id="result"></span></p>
    <p>Время: <span id="time"></span> мс</p>

    <script>
        // Загружаем Wasm модуль
        const go = new Go(); // из wasm_exec.js
        WebAssembly.instantiateStreaming(
            fetch("SwiftWasmDemo.wasm"), go.importObject
        ).then((result) => {
            go.run(result.instance);
        });

        function runSwift() {
            const n = parseInt(document.getElementById('input').value);
            if (typeof swiftFib === 'undefined') {
                alert("Модуль ещё не загружен!");
                return;
            }
            const start = performance.now();
            const result = swiftFib(n);
            const end = performance.now();
            document.getElementById('result').textContent = result;
            document.getElementById('time').textContent = (end - start).toFixed                

Блоги

Рекомендаций по книгам