Как эффективно встроить wasm (WebAssembly) непосредственно в файл html? типизированный массив - PullRequest
4 голосов
/ 04 мая 2020

Мне нужно встроить приложение wasm непосредственно в саму страницу html, а не загружать его (например, через xhr) из отдельного файла. До сих пор мне удавалось встраивать его, «печатая» байты прямо в массив Uint8Array (см. Ниже), но это не экономит место (очевидно). Файл wasm 65 МБ становится файлом 220 МБ js.

const go = new Go() WebAssembly.instantiate(new Uint8Array([0,97,115,109,1,0,0,0,0,242,128,128,128,0,10,103,111,46,98,117,105,108,100,105,100,255,32,71,111,32,98,117,105,108,100,32,73,68,58,32,34,56,69,84,87,98,97,65,117,88,67,100,52,98,55,72,90,112,90,114,70,47,85,111,66,116,82,89,102,80,118,83,101,111,69,111,106,117,50,85,99,90,47,115,77,71,110,85,106,....], { type: 'application/wasm' });

1 Ответ

0 голосов
/ 04 мая 2020

Эффективным способом кодирования модуля WebAssembly является использование кодировки Base64. Вы можете кодировать (в Узле) следующим образом:

const readFileSync = require('fs').readFileSync;

const wasmCode = readFileSync(id);
const encoded = Buffer.from(wasmCode, 'binary').toString('base64')

И декодировать в браузере или Узле следующим образом:

var encoded = "...";

function asciiToBinary(str) {
  if (typeof atob === 'function') {
    return atob(str)
  } else {
    return new Buffer(str, 'base64').toString('binary');
  }
}

function decode(encoded) {
  var binaryString =  asciiToBinary(encoded);
  var bytes = new Uint8Array(binaryString.length);
  for (var i = 0; i < binaryString.length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  return bytes.buffer;
}

var instance = WebAssembly.instantiate(decode(encoded), importObject)
      .then(r => r.instance);
...