feat: split bundler-friendly bundle in to individual VFSs to reduce import size#168
feat: split bundler-friendly bundle in to individual VFSs to reduce import size#168jurerotar wants to merge 2 commits into
Conversation
|
As we're at it, Emscripten just added support for the proposed Cross-Origin Storage (COS) API. I'd love if you could see if there's a way to (i) compile with the new flag and (ii) see if the JS bundles could be optimized for COS. This would be a pretty big lever given SQLite Wasm is used on many sites. Full disclosure: I'm on the team that wants to make COS happen in browsers. Having SQLite as a project supporter would be huge. Are you interested in looking into it, @jurerotar and @sgbeal. |
|
COS sounds awesome! Count me in, I'd happy to help with this! |
|
I created a test build with the cross-origin storage enabled, seems to (at least) build with no issues 😄 |
Amazing! The glue code might need some changes. If you install the COS extension and open a SQLite demo page using this build, you should see the Wasm binary be used (in DevTools, it loads a |
|
I hacked something together in https://googlechrome.github.io/samples/sqlite-wasm-cos/. Maybe you can extrapolate from there? I don't think this would work for all variants of the various scripts yet.
|
|
Alrighty, as you correctly assessed, SQLite-WASM uses a custom loader in the form of
@sgbeal, I know you haven't said yes to this work, but if I'm operating under the assumption that you will: do we still require |
|
i've not looked closely at any of this because (A) i'm nursing a newly-operated dog and (B) it's so hot there that my computer is off most of the time, but FWIW... i fully sympathize with the complaint and am not against, e.g., adding flags to the upstream build to filter select pieces out at build-time. The infrastructure is all there to support it. It's likely to be at least 2-3 weeks before i can explore that but am flagging this email thread so it COS i'm hearing of for the first time. The link says:
Until it's in one of the Big Three browsers and in progress in the other two, we're not likely to look twice at it upstream. |
It's no wonder that you hear about this the first time, it's relatively new. We have an extension that you can install to benefit from it today; it's a progressive enhancement. The chicken and egg problem for making it happen in ideally all browsers is to show developer demand, so if we can say SQLite uses this (just like Transformers.js, WebLLM, wllama, Flutter, and Emscripten today already*), this would be a huge lever. The cache benefits for a widely deployed resource like SQLite Wasm are real, and I'd love for you to take part in this. (Hope the dog is fine! ❤️🐶) —— |
|
I hope your dog has a speedy and painless recovery, Stephan! My solution for splitting modules is pretty brittle, because I have to split already generated code (https://github.com/jurerotar/sqlite-wasm/blob/a99c7de5234cbb57e846b1dac574c2c09ba7bc18/scripts/split-bundler-friendly-vfss.mjs) Stephan, if you're okay with it, I'd be happy to prepare an example PR on how we could implement the changes that I did in this PR, upstream. I would of course focus on backwards compatibility, so existing consumers wouldn't notice any difference. Main changes would be introducing a module system, so treeshakability becomes built-in at the source. If you then don't like my solution, we can think of an alternative one, or stick with this PR. Please let me know if this is something you'd like to see from my side! 😄 |
A long list of long-term commitments and responsibilities forces me to be highly selective, and features which aren't imminent in all of the major browsers are among the first to get filtered out as candidate side-projects. i won't quite say "never" but will point to the recent OPFS Web Locks addition as an example: Web Locks was never seriously considered as an option until it was in all of the Big Three Browsers.
She's recovering but it will be about two weeks before she can take the stairs and hop on and off the bed (until then i'm sleeping on the floor so that she won't rip her stitches trying to get into the bed). Sigh. #Parenthood Jure: We already have some pieces in place anticipating this capability but it's never been fleshed out. It's really just a matter of figuring out how it should plug it into the build process. This is just spitballing, but maybe just something like: defaulting to everything on for compatibility. The resulting :-? |
|
At Chrome, we're confident enough to put COS in Emscripten. What if Jure were to remodel the Wasm instantiation logic so it stays closer to Emscripten's (i.e., reducing the code you as SQLite are responsible for), would this be an option? Literally LOL'ing about your dog story. Hope you at least have a good air matress! |
It's still nowhere on my radar for the time being. My local bandwidth simply doesn't support nice-to-haves right now. This filtering of the build is arguably also nice-to-have, but it's one which has bugged me for a couple of years and some work has already been done in that direction so it won't be a big effort to get that working. COS, on the other hand, lives in a whole other scope. Maybe someday, but not today.
i'd completely forgotten about my air mattress, but it's too big for the current room arrangements :/. It was bought when i had to wait a few weeks for my furniture after moving in. |
|
BTW:
Search the makefile for "bare-bones". That removes all of the "optional" stuff from the WASM file but does not (AFAIR) affect the JS (which instead (currently) loads everything but skips adding bindings for optional C APIs which aren't in the WASM exports). Like you, we were underwhelmed at the amount of real savings so have never really explored a more modular build: $ make oz barebones=1 # oz=optimize for smaller size, barebones=1 omits a bunch of C APIs
...
$ ls -la jswasm/*.{mjs,wasm}
-rw-rw-r-- 1 stephan stephan 740572 Jun 23 22:05 jswasm/speedtest1.wasm
-rw-rw-r-- 1 stephan stephan 788310 Jun 23 22:06 jswasm/sqlite3-64bit.mjs
-rw-rw-r-- 1 stephan stephan 626136 Jun 23 22:05 jswasm/sqlite3-64bit.wasm
-rw-rw-r-- 1 stephan stephan 785423 Jun 23 22:06 jswasm/sqlite3.mjs
-rw-rw-r-- 1 stephan stephan 614096 Jun 23 22:05 jswasm/sqlite3.wasm
-r--r--r-- 1 stephan stephan 1516 Jun 23 22:05 jswasm/sqlite3-worker1-bundler-friendly.mjs
-r--r--r-- 1 stephan stephan 1499 Jun 23 22:05 jswasm/sqlite3-worker1.mjs
-r--r--r-- 1 stephan stephan 12692 Jun 23 22:05 jswasm/sqlite3-worker1-promiser-bundler-friendly.mjs
-r--r--r-- 1 stephan stephan 12675 Jun 23 22:05 jswasm/sqlite3-worker1-promiser.mjs
# mjs stripped of comments:
$ stripccomments < jswasm/sqlite3.mjs | wc
13883 33926 414149 |



I've wanted to do this one for a while, but I'll need feedback from both of you, @tomayac & @sgbeal, along with any other sqlite-wasm user, ideally,.
Currently, importing browser bundle adds about ~620KB (excluding sqlite3.wasm) to the total bundle size. This browser bundle isn't tree-shakable, so users have to load all of it, regardless of how much of it they actually need.
Quickly checking open-source projects, most users default to using a single VFS and don't use other ones, meaning there's a lot of unused code that folks still have to ship to their users.
This PR adds support for importing only individual VFSs. I've added types to make sure the split works correctly, along with narrowed types (so you can't use
kvvfsif you useopfs-wl).Rough comparison is here. We save roughly 150-200KB, depending on VFS used, which is around 50KB gzip on average. To be 100% honest, I was going for a bit larger numbers, but
coreis mostly Emscripten code and there's not much I can do about it.corecore + vtabcore + kvvfscore + opfscore + opfs-wlcore + opfs-sahpool