build(bundle): the app ships as one bundle - #305
Merged
Conversation
The splitter produced eleven JS chunks and two stylesheets, and every one of them was fetched on every visit — six under a kilobyte, which is request overhead and nothing else. It also cost a wave: app.js had to arrive and parse before the last node chunk was discovered, and the webfonts queued behind that, so they did not start until 132 ms on a local preview. kit.output.bundleStrategy: 'single' takes a visit from 17 requests to 5 — the page, the bundle, the stylesheet and the two font subsets actually needed — for +2 kB gzip, which is Rollup losing a little cross-chunk dedup. The fonts start at 122 ms instead. The trade is cache granularity: any change re-downloads the whole bundle rather than the chunk that moved. That is close to theoretical on GitHub Pages, which serves every asset with max-age=600 no matter what the immutable path claims. It is one config line with nothing else pointing at it, and the app behaves identically without it — only the waterfall gets longer, which nobody notices. So e2e/self-hosted.spec.ts counts the script and stylesheet responses now; reverting the line fails it with twelve scripts.
|
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.
Firefox's network tab on kneadtime.pizza showed 18 requests for one visit: eleven JS chunks, two stylesheets, two fonts, the document and the favicon. Six of those scripts were under a kilobyte — request overhead and nothing else — and all eleven were fetched on every visit, so the split was buying nothing.
It also cost a wave.
app.jshad to arrive and parse before the last node chunk was even discovered, and the webfonts queued behind that: they did not start until 132 ms on a local preview.What changed
kit.output.bundleStrategy: 'single'insvelte.config.js. Everything collapses tobundle.<hash>.js+bundle.<hash>.css.Measured on the real build, loading
/:The +2.1 kB is Rollup losing a little cross-chunk dedup; on a real connection one round trip is worth more than that.
The trade-off
Cache granularity: any change re-downloads the whole bundle rather than the chunk that moved. That is close to theoretical on GitHub Pages, which serves every asset with
cache-control: max-age=600regardless of theimmutablepath — checked against the live site.Why there is a test for a config line
Nothing else in the tree points at it, and the app behaves identically without it — only the waterfall gets longer, which is exactly the kind of regression a framework upgrade or a tidy-up removes unnoticed.
e2e/self-hosted.spec.tsnow counts the script and stylesheet responses on a real visit; reverting the config line fails it with twelve scripts. The spec was already the place that watches what the page fetches and from where, so this is the other half of the same question: how many times.Not in this change
messages.tsis ~173 kB raw / ~56 kB gzip and every reader downloads five languages to use one — roughly 40 % of the JS. Splitting it per locale is the real byte win, but it is a genuine refactor (the i18n singleton is synchronous at every call site) and it conflicts with a single bundle, which inlines dynamic imports. Worth its own change and its own decision.Checks
test-baseline.jsonraised to matchnpm run lintclean; version 7.0.4 (patch — no user-visible behaviour, no URL schema change)🤖 Generated with Claude Code