Repository navigation
perf(vendor): let the browser decompress x2t.wasm - #222
Merged
Merged
Conversation
The module ships brotli-compressed as x2t.wasm.br and every host declares Content-Encoding: br for it, so the browser decodes it at the network layer and instantiateStreaming compiles it straight off the response. 6,898,179 bytes on the wire against 9,483,006 for the best gzip we could produce -- 2.58 MB off the largest single download in the app -- and nothing in our code decompresses anything any more: sniffAndRebuild and the gzip branch of prepareWasmBinary are gone from both loaders, and canStreamWasm no longer asks for DecompressionStream. The .br extension and the absence of a Content-Type rule in _headers are both load-bearing. wrangler pages dev, which the e2e-pages job runs, re-compresses anything it considers compressible and overwrites Content-Encoding with its own result; a pre-encoded asset then arrives double-encoded and no browser API can decode brotli to recover. It leaves application/octet-stream alone, which is what an unrecognised extension gets. Name the file .wasm, or declare a Content-Type for it, and the editor stops loading under that job. The loader labels the response application/wasm itself, so nothing depends on the host typing it. Verified in all three local environments: vite preview (full 160-spec suite), wrangler pages dev, and static-web-server with sws.toml. Real Cloudflare Pages is covered by the preview-smoke job. Reverse-validated: removing the Content-Encoding line from _headers turns the new hosting-contract case red. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKNHFQ1kek1cHeqhbH37Pk
chaxus
enabled auto-merge (rebase)
September 12, 2026 06:43
Deploying document with
|
| Latest commit: |
757a129
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://15888a8c.document-7hm.pages.dev |
| Branch Preview URL: | https://perf-wasm-content-encoding.document-7hm.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The x2t module ships brotli-compressed as
x2t.wasm.br, and every host declaresContent-Encoding: brfor it. The browser decodes it at the network layer, soinstantiateStreamingcompiles the module straight off the response and nothing in our code decompresses anything.DecompressionStream('gzip')in JS2.58 MB off the largest single download in the app, and ~100 lines gone from the two loaders that had to stay in step with each other (
x2t_helper.jsandpackages/converter):sniffAndRebuildin both, the gzip branch ofprepareWasmBinaryin both, and theDecompressionStreamcapability check.Idea taken from a third-party local-first Office site (see #219), verified against their production deployment before starting.
The part that took the time
wrangler pages dev— whate2e-pagesruns — re-compresses responses and overwritesContent-Encodingwith its own result. A pre-encoded asset then arrives double-encoded, and no browser API can decode brotli to recover. The suite went red onran: false; x2t never instantiated.--compatibility-flags brotli_content_encodingmakes no difference. What wrangler does respect is its own compressibility rule: it leavesapplication/octet-streamalone, and that is what an unrecognised extension gets.So two things are load-bearing and neither looks it: the
.brextension, and the absence of aContent-Typerule for that path in_headers. AddingContent-Type: application/wasmthere is enough to make wrangler compress it again (row 4 — that is how this was first written). Both are documented in_headersnext to the rule. The loader labels the responseapplication/wasmitself, so nothing depends on the host typing it.Verified
test:e2e)vite.config.tsmiddlewaree2e-pages)public/_headerse2e-docker)sws.tomltwin rulepublic/_headerspreview-smokeon this PRWhat stays
The
instantiateWasmhook — no longer decompressing, but still carrying the fetch retry (the CF 500 of 2026-08-20) and the two-way failure reporting the open-failure guard needs. The buffered fallback stays too, now four lines.After a vendor upgrade
vendor-contractpins the sha256 of the decompressed module (unchanged by this migration —7db02f5c…, which is how we know the recompression is lossless) and bounds the compressed size.Reverse validation (convention 5): removing the
Content-Encodingline from_headersturns the new hosting-contract case red.🤖 Generated with Claude Code
https://claude.ai/code/session_01MKNHFQ1kek1cHeqhbH37Pk