Skip to content
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

Implement caching of wasm compilation in our shell .html file #4711

Closed
juj opened this issue Nov 9, 2016 · 14 comments
Closed

Implement caching of wasm compilation in our shell .html file #4711

juj opened this issue Nov 9, 2016 · 14 comments

Comments

@juj
Copy link
Collaborator

juj commented Nov 9, 2016

Since in wasm we need to cache explicitly to IndexedDB, implement an easy code snippet to bundle the machinery to do so so that it matches the way that asm.js works, for people who don't need to care about specific details of caching.

@juj
Copy link
Collaborator Author

juj commented Nov 9, 2016

(@kripken: I can work on this as well)

@kripken
Copy link
Member

kripken commented Nov 9, 2016

Sounds good, thanks. I think we just need a little code in emcc.py for this, around where we load the wasm binary, adding another async step inside it.

Although, it might be nice to consider caching more generally, perhaps we could share code with the asset cache? Just a thought.

@kripken
Copy link
Member

kripken commented Dec 21, 2016

We should also use the async wasm compilation APIs while adding this async caching stuff.

@kripken
Copy link
Member

kripken commented Dec 31, 2016

From discussion in that issue, we also need to have the imports present when using the new async compilation APIs, and that's not easy to make work because (1) we have the imports only in the middle of the JS, so we can't fire of compilation in the HTML, and (2) we synchronously send the imports and receive the exports.

Long-term we might want to look for a new compilation mode that is fully async. In the short term, the best option seems to be to add an indirection layer on the exports, perhaps like SWAPPABLE_ASM_MODULE which we already have, and add a run dependency on compilation. Then the exports are available synchronously to be captured, so we don't break code, and we can use the new async+imports API. Hopefully the indirection overhead will be low.

@juj, I can do that async stuff, but all this interacts with caching, so we should probably plan it all together here before we start.

@kripken
Copy link
Member

kripken commented Dec 31, 2016

(We should probably open an issue for the async+imports stuff specifically, but delaying that so we can do the planning here in one place due to the interaction with caching.)

@kripken
Copy link
Member

kripken commented Jan 18, 2017

Async+imports PR is now up: #4867

I don't think it affects the IndexedDB stuff. Should be easy to fit in.

@drhouse82
Copy link

Actually, I find myself being one of these users being named in the inital post...
I use an opencv port as wasm, I believe it's an embind module. https://github.com/njor/opencvjs
To reduce startup time, I would like to cache it to indexeddb.
Is there any way I can do this with the embind module, or do I need to instantiate the .wasm like described in this article? https://developer.mozilla.org/en-US/docs/WebAssembly/Caching_modules

@juj
Copy link
Collaborator Author

juj commented Jul 14, 2017

Embind would not interact with caching wasm to IndexedDB. Currently we don't yet have a built-in machinery to cache wasm to IndexedDB. The reason has been that a simple caching scheme is probably useful only to get started, but in a real world shipped application one will want to make sure wasm download, compilation and caching is done parallel with other site load actions and that the cache is integrated with other cached data so that apps don't need to interact with several caches. At that point, people would be asking how to disable any built-in wasm caching so that it doesn't get in the way.

You can follow the MDN guide to do this to your .html shell page. Another example you can follow is the html page at http://mzl.la/webassemblydemo, which hooks into Emscripten runtime to manually download and cache.

@drhouse82
Copy link

Thanks a lot for that info. I'll look into the zen garden demo.

@kripken
Copy link
Member

kripken commented Apr 9, 2018

Thinking a little about this now, the best guidelines seem to be at

https://developer.mozilla.org/en-US/docs/WebAssembly/Caching_modules

with example code. I am a little worried about code size, though. Perhaps we should have it as an option?

@sunfishcode made a good point offline, that for small wasm files you really don't want caching anyhow (they compile quickly, and the overhead of doing IDB operations might be larger; and for them, the code size of adding IDB handling is more noticeable). So perhaps this should be on or off by default based on the wasm size? Makes logical sense, although it may be somewhat surprising in practice.

@sim642
Copy link

sim642 commented Jul 1, 2018

What's the plan with this issue? The outcome of PR #6661, which was an attempt to implement this, makes it sound like wasm caching will not be a thing still. Is it going to be just a wait until a different caching mechanism is agreed on?


Slightly contrary to the IDB direction, I've still been looking into doing IDB caching in my application for the time being. instantiateWasm implemented in PR #5055 provides some of the means to accomplish this, i.e. provide instances oneself. That, however, also requires doing the whole first fetching of the wasm module manually, not via the means already existent in the preamble.

I feel like it might be useful to expose the WebAssembly.Module (and maybe WebAssembly.Instance) created by emscripten in the emscripten module as wasmModule (from receiveInstance) to make it possible to cache an already fetched and created module, instead of having to duplicate the fetching and its fallback manually. Having access to the module and the instance might be useful for other purposes too, no?

It would make it even possible to manually give the wasmModule to emscripten to use instead of having to do it through the instantiateWasm callback. I'm wondering if such addition could be reasonable to have for something other than trying to still use the dying IDB caching.

@kripken
Copy link
Member

kripken commented Jul 1, 2018

Browsers have decided that IDB is not the best way to cache wasm compilations, and there is work on alternatives that are more promising (simpler, more likely to work consistently, etc.). Hopefully we'll have something to experiment with there soon.

We could add an option to save the wasm module and instance, if it's useful. I think we don't want it on by default though, as if the module and instance are not saved anywhere the browser may be able to free some memory.

@sim642
Copy link

sim642 commented Jul 2, 2018

That's a fair point I didn't consider. I suppose an optional callback like onReceiveInstance or similar could be better memory-wise and always be included. Still, I'm not sure how much emscripten needs it otherwise if the only use would be to implement the outdated IDB caching. If there's no other point for having this, I feel like there's no point in implementing it either. I have just hacked my custom build to still make it possible.

@stale
Copy link

stale bot commented Sep 18, 2019

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants