Перейти к содержанию

Уменьшение размера .wasm

Для .wasm-бинарников, которые мы отдаём клиентам по сети — как в нашем веб-приложении «Игра жизни» — важно следить за размером кода. Чем меньше .wasm, тем быстрее загружается страница и тем лучше для пользователей.

Насколько можно уменьшить .wasm «Игры жизни» за счёт настроек сборки?

Немного времени на обзор опций сборки, которые можно подкрутить для меньшего размера .wasm.

При стандартной конфигурации release-сборки (без отладочных символов) наш WebAssembly-бинарник занимает 29 410 байт:

1
2
$ wc -c pkg/wasm_game_of_life_bg.wasm
29410 pkg/wasm_game_of_life_bg.wasm

После включения LTO, установки opt-level = "z" и запуска wasm-opt -Oz итоговый .wasm сжимается всего до 17 317 байт:

1
2
$ wc -c pkg/wasm_game_of_life_bg.wasm
17317 pkg/wasm_game_of_life_bg.wasm

А если сжать его gzip (как делает почти каждый HTTP-сервер), получается скромные 9 045 байт!

1
2
$ gzip -9 < pkg/wasm_game_of_life_bg.wasm | wc -c
9045

Упражнения

  • С помощью утилиты wasm-snip уберите из .wasm «Игры жизни» инфраструктурные функции для паники. Сколько байт это экономит?

  • Соберите крейт «Игра жизни» с wee_alloc в качестве глобального аллокатора и без него. В шаблоне rustwasm/wasm-pack-template, с которого мы начинали проект, есть cargo-фича wee_alloc: её можно включить, добавив её в ключ default в секции [features] файла wasm-game-of-life/Cargo.toml:

    1
    2
    [features]
    default = ["wee_alloc"]
    

    Насколько уменьшается размер .wasm при использовании wee_alloc?

  • Мы создаём только один экземпляр Universe, поэтому вместо конструктора можно экспортировать операции, которые работают с одним глобальным экземпляром static mut. Если этот глобальный экземпляр использует двойную буферизацию из предыдущих глав, буферы тоже можно сделать глобальными static mut. Тогда в реализации «Игры жизни» не остаётся динамического выделения памяти, и крейт можно сделать #![no_std] без аллокатора. Насколько уменьшился .wasm после полного отказа от зависимости на аллокатор?

Комментарии