-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Size limits with synchronous WebAssembly functions #1499
Comments
If > 4k is bad for the main thread, it's probably bad for service worker startup & a fetch event too. I'm leaning towards adding the same restrictions on these APIs. |
Hi @jakearchibald, Would you mind looking though the discussion that @Pauan and I had, in the issue that he linked? If it is no longer possible to run WebAssembly before registering the listeners, this effectively requires writing business logic in javascript that some people (me among them) currently have in WebAssembly. What kind of solution do you think could be available for that situation? |
The summary is that @moshevds wants to write their service worker entirely in Wasm, without any JS at all. Right now that's not possible, because:
So right now it's not really possible to create a service worker which is pure Wasm. Instead you have to create a // This fetches a file and automatically caches it, so that way it will work offline.
async function load(url) {
const cache = await caches.open("offline");
try {
const response = await fetch(url);
if (response.ok) {
await cache.put(url, response.clone());
return response;
} else {
throw new Error("Invalid status code: " + response.status);
}
} catch (e) {
const response = await cache.match(url);
if (response) {
return response;
} else {
throw e;
}
}
}
// This loads the glue code which is auto-generated by wasm-bindgen.
importScripts("./path/to/foo.js");
// This loads the .wasm file in the background and returns a Promise.
const wasm = wasm_bindgen(load("./path/to/foo_bg.wasm"));
// The `waitUntil` ensures the .wasm file is loaded, so that way we
// can call functions defined within the .wasm file.
self.addEventListener("install", (event) => {
event.waitUntil(wasm);
});
self.addEventListener("fetch", (event) => {
// This calls the `fetch` function which is defined within the .wasm file.
event.waitUntil(wasm.then(() => wasm_bindgen.fetch(event)));
}); wasm-bindgen cannot generate the above code, because wasm-bindgen doesn't know what events the user wants, and wasm-bindgen also doesn't know what caching strategy the user wants, since wasm-bindgen is just a compiler. So, each user of wasm-bindgen must write the above code, and it's pretty easy to get wrong (especially with regard to caching). From wasm-bindgen's perspective, the ideal solution is for the browser to have built-in support for Removing the 4 KB limit also removes the need for the above code, but it isn't a great solution, since it still requires base64-encoding the |
Thank you @Pauan for that summary and description of my goal. I do want to add that embedding base64 is what I am already doing, in anticipation of built-in support. |
P.S. The But that's a separate orthogonal concern, and that still doesn't remove the need to define a separate |
Also, I want to make it really clear what our situation is:
Right now, this works great... except in service workers. Service workers require you to synchronously define the event listeners, but Therefore, you cannot define the event listeners in your Rust code. Instead, the user of wasm-bindgen must create a separate Even though wasm-bindgen is already generating So every user of wasm-bindgen must create their own So from wasm-bindgen's perspective, there are three possible solutions to this:
Option 1 is ideal for us, option 2 isn't as good but it's okay, and option 3 is the worst but is acceptable. |
I think we should continue to aim for 1, first-class support for Wasm service workers and enabling Wasm to use IDL-defined APIs. |
I don't know. |
Hi all. I remain worried about this possible restriction, because I don't see a sensible alternative. Is it safe to assume this limit will not be introduced before first-class wasm support is available in browsers? Clarity about this would allow me to work with the wasm-bindgen project to allow it to act as a shim for the first-class wasm support being aimed at. If not here, what is the best place to find this clarity? |
Right now the synchronous
new WebAssembly.Module(foo)
/new WebAssembly.Instance(foo, bar)
functions have a 4 KB size limit on the main thread, because they block the event loop.However, you can use them in regular workers without the 4 KB limit.
Should they be allowed in service workers with or without the 4 KB limit?
The text was updated successfully, but these errors were encountered: