From e1aea95ec90ac9f1b32d23bb1aa556f8c1edfdf2 Mon Sep 17 00:00:00 2001 From: Jeremy Leibs Date: Thu, 12 Dec 2024 16:36:12 +0100 Subject: [PATCH] Fix broken notebook loading on firefox by compressing the encoded wasm payload (#8426) ### Related - Resolves: https://github.com/rerun-io/rerun/issues/8154 ### What It turns out firefox doesn't let you create a dataurl larger than 32MB. Although our `.wasm` was under this threshold, the overhead of base64-encoding pushed us over the threshold. However, as we were encoding the raw, uncompressed .wasm, we still actually have plenty of margin... we just need to jump through more hoops to use it now. Using DecompressionStream like this seems to be generally available across our target browsers so I think we should be good? --- rerun_js/web-viewer/bundle.mjs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/rerun_js/web-viewer/bundle.mjs b/rerun_js/web-viewer/bundle.mjs index c93feaf232b1..ac79ec9611f8 100644 --- a/rerun_js/web-viewer/bundle.mjs +++ b/rerun_js/web-viewer/bundle.mjs @@ -6,12 +6,13 @@ import { fileURLToPath } from "node:url"; import * as path from "node:path"; import * as fs from "node:fs"; +import * as zlib from "node:zlib"; import * as util from "node:util"; const __filename = path.resolve(fileURLToPath(import.meta.url)); const __dirname = path.dirname(__filename); -const wasm = fs.readFileSync(path.join(__dirname, "re_viewer_bg.wasm")); +const wasm = zlib.gzipSync(fs.readFileSync(path.join(__dirname, "re_viewer_bg.wasm"))); const js = fs.readFileSync(path.join(__dirname, "re_viewer.js"), "utf-8"); const index = fs.readFileSync(path.join(__dirname, "index.js"), "utf-8"); @@ -19,12 +20,17 @@ const INLINE_MARKER = "/**/"; /** @param {Buffer} buffer */ function buffer_to_data_url(buffer) { - return `data:application/wasm;base64,${buffer.toString("base64")}`; + return `data:application/octet-stream;gzip;base64,${buffer.toString("base64")}`; } -async function data_url_to_buffer(dataUrl) { - const response = await fetch(dataUrl); - return response.arrayBuffer(); +async function compressed_data_url_to_buffer(dataUrl) { + const response = await fetch(dataUrl); + const blob = await response.blob(); + + let ds = new DecompressionStream("gzip"); + let decompressedStream = blob.stream().pipeThrough(ds); + + return new Response(decompressedStream).arrayBuffer(); } const inlined_js = js.replace("export default function", "return function"); @@ -35,9 +41,9 @@ async function fetch_viewer_js() { } async function fetch_viewer_wasm() { - ${data_url_to_buffer.toString()} + ${compressed_data_url_to_buffer.toString()} const dataUrl = ${JSON.stringify(buffer_to_data_url(wasm))}; - const buffer = await data_url_to_buffer(dataUrl); + const buffer = await compressed_data_url_to_buffer(dataUrl); return new Response(buffer, { "headers": { "Content-Type": "application/wasm" } }); } `;