Performance
What a build already does to be fast, how to see what it weighs, budgets that warn, and the few things that make a site slow.
What the build does already
- Only the runtime you use. The runtime is a set of modules; a build keeps the ones its code reaches. A page of static text carries 3 of its 37 modules: an
app.jsof 11 kB, 3.7 kB gzipped. - A chunk per page.
build.split(on by default) writes each page's code and styles as their own files, loaded when its route is first shown. - Pre-rendered HTML with
build.ssg: the first paint needs no script. - One pruned stylesheet. Only the built-ins you use, only the tokens something names.
- Precompressed. A
.gzbeside every text file, for a host that serves it;wf servesends the same bytes, so Lighthouse against the dev server measures what a deploy sends. - Images at every width, with
width/heightso nothing shifts, a placeholder while they load, the first one eager and the rest lazy (Media). - Minified output (
build.minify).
Seeing what it weighs
bash
text
What it weighs
app.js 47.6 kB (14.6 kB gzipped) +20 B
styles.css 16.9 kB (3.7 kB gzipped)
index.html 5.1 kB (1.3 kB gzipped)
pages/Suggest.js 2.2 kB (0.8 kB gzipped)
pages/Home.js 1.4 kB (0.6 kB gzipped)
…
total 90.7 kB
Runtime: 14 of 37 modules, 89.3 kB of 220.3 kB (before minifying)
core 19.6 kB always
motion 16.6 kB needed by when, match, each, router
form 12.1 kB WF.form
router 10.7 kB WF.router
store 6.5 kB WF.store
…
left out: helpers format offline peer scalars text slot show browser …
Tokens: 26 nothing in the output names, left out
That is the tutorial's site: a form brings form and field, a store store and keep, a second page router.
Each build records its sizes in .wf-sizes.json, so the next --stats shows what moved. Each runtime module is listed with what reached it — the first place to look when a module you did not expect is in.
Budgets
json
{ "build": { "budget": { "app.js": "40 kB", "styles.css": "30 kB", "pages/Home.js": "10 kB" } } }
A gzipped size an output should stay under. Going over prints a warning and the build goes on; a CI job that wants to fail on it can read the same numbers.
Timing it in a browser
bash
wf verify loads every route in headless Chrome and prints its first contentful paint, the nodes in the document and the bytes and requests it took; --budget fails a route slower than that. Lighthouse and the browser's performance panel work on the build as on any site.
What makes a site slow
- A large
datafile.data posts = "posts.json"is inlined into the bundle, so a 2 MB file is 2 MB of JavaScript. Keep build-time data to what pages show; fetch the rest, or split it across pages that each read one. - A waterfall of fetches. A resource whose URL depends on another's answer waits for it. Where you can, ask for both at once, or have the server send them together.
- Layout decided by
viewport. It is unknown until the script runs, so the page paints one branch and swaps. Use responsive values, which are CSS. runtime: "full". It ships every module. Only needed when a hand-written script callsWFin ways the build cannot see.- Web fonts. Each weight is a download. Use
display=swap, few weights, or the baseline's system fonts. - Unkeyed lists that change.
for item in itemsrebuilds the list;for item in items by item.idmoves the nodes that stayed. - Pictures from
public/. They are copied as they are. Declare them withimageto get every width and a placeholder.
On this page
What the build does already Seeing what it weighs Budgets Timing it in a browser What makes a site slowChecked by the test suite
Every code block in the guide is parsed, checked and type-checked on each release.