From 118319bd6f74fc108f5309c0b4a9693df7d3211a Mon Sep 17 00:00:00 2001 From: torfmaster Date: Mon, 28 Oct 2024 13:55:50 +0100 Subject: [PATCH] feat: use base64 encoding to speed up loading --- crates/cli-support/src/js/file_util.rs | 17 +++++++++++++++++ crates/cli-support/src/js/mod.rs | 15 ++++++--------- crates/cli-support/src/wasm2es6js.rs | 16 +++------------- 3 files changed, 26 insertions(+), 22 deletions(-) create mode 100644 crates/cli-support/src/js/file_util.rs diff --git a/crates/cli-support/src/js/file_util.rs b/crates/cli-support/src/js/file_util.rs new file mode 100644 index 000000000000..772a10ad6097 --- /dev/null +++ b/crates/cli-support/src/js/file_util.rs @@ -0,0 +1,17 @@ +use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine}; + +pub(crate) fn create_load_inline_bytes_snippet(bytes: &[u8], variable_name: String) -> String { + format!( + " + let {variable_name}; + const base64 = \"{base64}\"; + if (typeof Buffer === 'undefined') {{ + {variable_name} = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); + }} else {{ + {variable_name} = Buffer.from(base64, 'base64'); + }} + ", + variable_name = variable_name, + base64 = BASE64_STANDARD_NO_PAD.encode(&bytes), + ) +} diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index dbf9e05ba6cf..b08412034332 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -10,6 +10,7 @@ use crate::wit::{JsImport, JsImportName, NonstandardWitSection, WasmBindgenAux}; use crate::{reset_indentation, Bindgen, EncodeInto, OutputMode, PLACEHOLDER_MODULE}; use anyhow::{anyhow, bail, Context as _, Error}; use binding::TsReference; +use file_util::create_load_inline_bytes_snippet; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt; @@ -19,6 +20,7 @@ use std::path::{Path, PathBuf}; use walrus::{FunctionId, ImportId, MemoryId, Module, TableId, ValType}; mod binding; +pub(crate) mod file_util; pub struct Context<'a> { globals: String, @@ -308,19 +310,14 @@ impl<'a> Context<'a> { fn generate_inline_wasm_loading(&mut self) -> String { let mut shim = String::new(); - let buf = self.module.emit_wasm(); + let wasm = self.module.emit_wasm(); + + let serialized = create_load_inline_bytes_snippet(&wasm, "bytes".into()); - let mut serialized = "const bytes = new Uint8Array([".to_string(); - let (last, bytes) = buf.split_last().unwrap(); - for byte in bytes { - serialized.push_str(&format!("{},", byte)); - } - serialized.push_str(&format!("{}", last)); - serialized.push_str("]);"); shim.push_str(&serialized); shim.push_str( " - const wasmModule = new WebAssembly.Module(bytes.buffer); + const wasmModule = new WebAssembly.Module(bytes); const wasmInstance = new WebAssembly.Instance(wasmModule, imports); wasm = wasmInstance.exports; module.exports.__wasm = wasm; diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index 36298fdd54e2..f5688db697da 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -1,9 +1,10 @@ use anyhow::{bail, Error}; -use base64::{prelude::BASE64_STANDARD, Engine as _}; use std::collections::HashSet; use std::fmt::Write; use walrus::Module; +use crate::js::file_util::create_load_inline_bytes_snippet; + pub struct Config { base64: bool, fetch_path: Option, @@ -232,18 +233,7 @@ impl Output { let wasm = self.module.emit_wasm(); let (bytes, booted) = if self.base64 { ( - format!( - " - let bytes; - const base64 = \"{base64}\"; - if (typeof Buffer === 'undefined') {{ - bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); - }} else {{ - bytes = Buffer.from(base64, 'base64'); - }} - ", - base64 = BASE64_STANDARD.encode(&wasm) - ), + create_load_inline_bytes_snippet(&wasm, "bytes".into()), inst, ) } else if let Some(ref path) = self.fetch_path {