Field notes · was Appendix C, in part
Make it fast
The book argues that performance is a feature, not a polish — that fast is a feature, slow is a bug, and waiting is where you lose the person you worked so hard to serve. That is the posture, and it stayed in print. This is the craft, and it lives here because it goes stale.
Last reviewed 2026-09-04
The mindset#
Performance work fails when it is vague good intentions and succeeds when it is a budget: a concrete target the software must meet to be considered done, enforced from the start rather than bolted on at the end.
The reason it gets neglected is specific and fixable: you build on a fast machine, on a fast network, and your users don't. The software feels fast to you, always, no matter how bloated it gets, and you ship that false feeling to someone on a three-year-old mid-range phone on patchy mobile data. The gap between your conditions and theirs is where every performance disaster hides, unseen, because you literally cannot feel it from your desk.
So, deliberately
- Throttle your own network and CPU in the browser's dev tools, and leave it throttled for a whole afternoon.
- Keep a cheap real device on your desk and test on that, not on the simulator.
- Watch field data from real users, not only lab scores. Your impression is not evidence.
The three questions#
The industry's metric names keep changing — the current set already replaced an earlier generation, and one of them was renamed and replaced again since the book's appendix was written. The three questions underneath them do not change:
- Does it appear fast? How long before the main content is on screen.
- Does it respond fast? How long before it reacts to a tap or a keystroke.
- Does it stay still? How much the layout jumps around while it loads.
Pick targets for those three, measure them under real-user conditions, and treat missing them as a bug rather than as a nice-to-have. Whatever this year's metric is called, it is measuring one of the three.
Payload: the less you send, the faster it is#
Almost all web slowness, at the root, is too much stuff sent over a network that is slower and less reliable than the CPU. Every byte you do not send is a byte that cannot be slow.
In order of payoff
- Compress everything in transit. Text assets compress dramatically, and serving them uncompressed is leaving a free win on the table. It is usually a server configuration flip, and it is astonishing how often it is off. Check it first.
- Ship only the code the page needs. JavaScript costs twice — network to download, CPU to parse and execute — and the CPU half lands hardest on exactly the cheap phones your users have.
- Audit the dependencies. The heaviest payload on most pages is libraries: the convenient package that dragged in a megabyte to save an afternoon. Every library you add, your user downloads and runs, on their phone, on their data plan.
Images and video#
After code, images are almost always the bulk of a page's weight — and the richest vein of easy wins.
- Send the right size for the device. The cardinal sin is shipping a desktop-sized image to a phone that displays it at a fraction of the size. Offer the browser several sizes and let it choose.
- Use the current efficient format, not the legacy one out of habit. The specific best format keeps advancing; the discipline does not.
- Resize and strip before shipping. Ship the dimensions you display, and strip the embedded camera data, location, thumbnails and colour profiles — invisible to the user, pure weight.
- Send fewer images. Gradients, simple shapes, decorative flourishes and many icons can be CSS at a fraction of the weight, and they scale perfectly. Ask whether it needs to be an image at all.
- Video is the heaviest thing a page can carry. Be deliberate, and think hard before sending it to a phone on cellular data at all. Strip silent audio tracks from decorative video — you are paying weight for sound nobody will hear.
The device itself#
- Mind the battery. The constantly-running animation, the script polling every hundred milliseconds, the work nobody asked for — these do not just slow the page, they drain the phone. Idle when you can; don't animate what isn't visible.
- Set the viewport. The one-line declaration that tells the browser to render at the device's actual width is the foundation everything responsive sits on, and it is still, somehow, sometimes missing.
- Accessibility belongs in this list. Performance and accessibility are the same question from two angles: does the software actually work for the human in front of it, whatever their device, network or ability. Both are far cheaper built in than retrofitted.
Offline: the web that survives the tunnel#
A normal page is helpless the instant the signal drops — and your users' signal drops constantly, in tunnels, lifts, buildings, trains: exactly the mobile moments they are most likely to be using your software. An application that has cached its essentials keeps working when the network does not. This is design for error applied to the most common error on mobile: the network simply not being there.
And a note that has aged well: be sceptical of any “magic fast” framework that asks you to surrender control of your own pages in exchange for speed you could earn directly with the disciplines above. The open web tends to catch up with the walled fast-lanes. It did before.
This site's own numbers#
A page about performance ought to be the fastest page you load today, and ought to show its working. These figures are generated from the built site by a script, not typed by hand.
| Homepage document, gzipped | 6.0 KB |
|---|---|
| Fonts on a first view | 72.8 KB |
| First view, total | 78.8 KB |
| All fonts the site can ever serve | 79.6 KB |
| JavaScript bundles | none |
| JavaScript inlined in the page | 0.7 KB |
| Heaviest page, gzipped | 14.1 KB — /against/ |
| Every page on the site, gzipped, together | 137.0 KB |
Where the font weight goes
| nr-text.woff2 | 32.9 KB |
|---|---|
| nr-display.woff2 | 20.3 KB |
| nr-italic.woff2 | 19.6 KB |
| nr-greek.woff2 | 6.7 KB |
How it was kept small
- One typeface, cut three ways. The site ships Newsreader as three purpose-built instances — a text cut, an italic and a display cut — subset to the characters the site actually uses, with the variable axes pinned rather than shipped whole. The uppercase labels and the monospaced note-fragments use faces already on your device and cost nothing.
- No framework at runtime. The pages are static HTML. The only JavaScript the site ships is the colour-theme toggle — inlined, not bundled, which is why the row above reads bytes rather than files — and everything works with it switched off. Nothing is loaded from someone else's CDN: no framework, no fonts, no tag manager. The one exception is the page-view counter Cloudflare adds as the page leaves its network; it is not in the build, so it is not in these numbers, and it is the whole of what counts you.
- No images. The one graphic on this site is a one-pixel red line, drawn in CSS.
- Stylesheet inlined. A first visit costs no extra round trip; the whole design system is small enough that this is the right trade.
What these numbers do not tell you: how fast the page felt on your device, on your network, today. Only you can measure that, which is the whole argument of this page.
What has changed since the book#
This section exists so you can tell how much drift there has been, and is the reason this material left the printed book at all.
- 2026-09-04
- First web version. Metric names generalised to the three durable questions; the appendix's specific thresholds removed rather than frozen. The framework obituary kept, as an example of the pattern rather than as news.
Every byte and every cycle you spend is spent on their battery, their data, their patience. Spend it like it is theirs. It is.