Use streaming compilation on both Cross-Origin Storage paths - #27609
Merged
Conversation
The COS integration added in emscripten-core#27066 read the module into an ArrayBuffer on both the cache-hit and cache-miss paths and called WebAssembly.instantiate(), losing the download/compile overlap that the standard instantiateStreaming() path provides. Cache hit: wrap File.stream() in a Response with an application/wasm content type and pass it to instantiateStreaming(). Cache miss: tee() the fetch body so one branch feeds instantiateStreaming() while the other is piped into COS in the background. pipeTo() closes the writable, and COS verifies the hash on close. If the store fails before consuming, the tee branch is cancelled so the body is not buffered indefinitely. Also updates the docs and the custom instantiateWasm example to match.
This was referenced Aug 25, 2026
sbc100
approved these changes
Aug 25, 2026
tomayac
enabled auto-merge (squash)
August 25, 2026 18:30
sbc100
approved these changes
Aug 25, 2026
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.
Follow-up to #27066. The Cross-Origin Storage integration read the module into an
ArrayBufferon both the cache-hit and cache-miss paths and calledWebAssembly.instantiate(), so enabling-sCROSS_ORIGIN_STORAGElost the download/compile overlap of the standardinstantiateStreaming()path. Every first-visit user hit the slower miss path. (Thanks to @reillyeon for spotting this in WICG/cross-origin-storage#74.)Cache hit:
handle.getFile().stream()is wrapped in aResponsewith anapplication/wasmcontent type and passed toinstantiateStreaming(). The bytes were hash-verified when written into COS, so the fixed type is safe.Cache miss: the fetch body is
tee()'d. One branch goes toinstantiateStreaming()immediately; the other ispipeTo()'d into the COS writable in the background (pipeTo()closes the writable, and COS verifies the hash on close). If the store fails before consuming, the tee branch is cancelled so the body is not buffered indefinitely.The server's MIME type is deliberately not forwarded on the miss path: the standard path recovers from a bad MIME type by re-downloading, but here the store branch is already consuming the body. A wrong file still fails compilation and falls through to the standard path as before. A non-OK response now throws early rather than being handed to the compiler.
Docs, the custom
Module['instantiateWasm']example, and the ChangeLog are updated to match. No test changes: the existingtest_cross_origin_storage_*browser tests exercise both paths and the instrumentation callbacks fire at the same points.