Looks fast vs is fast: a practical performance budget
Performance improves when a team decides what it is willing to spend before the page is designed, instrumented, and filled with media.
A page can look fast in a design review and feel slow in a customer’s hand. The gap appears when performance is treated as a final engineering pass rather than a constraint shared by content, design, and code.
A performance budget makes the constraint explicit. It sets limits for the work the browser must do and targets for the experience a visitor should receive. The numbers are not universal standards. They are a starting position the team can tighten or relax deliberately when the product earns the cost.
Budget the experience and the payload
Experience targets describe the result: the main content appears quickly, the page stays still, and interactions respond without hesitation. Payload limits control likely causes: images, fonts, JavaScript, CSS, and third-party work. You need both. A small download can still perform poorly if it blocks rendering or does expensive work at the wrong moment.
For a mostly static studio or product-marketing page, this is a useful opening budget on a mid-range mobile device and an ordinary mobile connection:
- Largest visible content rendered in under 1.8 seconds in the test profile.
- Layout shift held below 0.05 for a calm, stable first view.
- Interaction latency kept below 200 milliseconds.
- Initial compressed JavaScript below 150 KB unless the page is an application.
- Above-the-fold image payload below 250 KB on the mobile source.
- Initial font payload below 100 KB, with no unused family or weight.
- No third-party script without a named owner and a measurable reason.
These are QDev working limits, not promises that fit every product. A mapping tool, editor, or data-heavy application will spend differently. The point is to state the exception rather than letting the budget disappear one dependency at a time.
Spend the hero budget once
The first view is where teams most often spend performance twice: a large visual asset arrives while custom fonts, animation code, analytics, and a client-rendered layout compete for the same moment. Decide what carries the idea. If the work needs a product film, the type and motion around it should become quieter. If the proposition is strongest as language, do not add a showreel to prove the page was expensive.
Serve an asset sized for the slot, not the source file exported by the camera or design tool. Give it explicit dimensions so the layout reserves space. Use a useful poster for video. Load the image that is actually visible first and defer the gallery below it. Restraint here improves both speed and hierarchy.
Treat fonts as interface code
Typography changes layout, so font loading is not a cosmetic concern. Every family, weight, script, and variable axis has a cost. Start with the characters and styles the product uses, subset when licensing and tooling permit it, and define a fallback with similar metrics so the page does not jump when the final face arrives.
Avoid preloading every font because preloading sounds fast. It raises priority, which means those files compete with something else. Preload only what the first view actually needs. A display face used once below the fold can wait. A system face may be the right answer for application UI even when the marketing page has more typographic character.
Make JavaScript justify itself
JavaScript is expensive beyond its transfer size: it must be parsed, compiled, and executed, often on a device slower than the one used to build the site. A static sentence does not need to hydrate. A server-rendered list does not need a client state library. An entrance effect does not deserve a large animation runtime by default.
Keep interactive boundaries small. Prefer platform behaviour for disclosure, forms, focus, scrolling, and media where it meets the product need. Load complex tools when a visitor asks for them. Review bundle changes in pull requests just as you would review a new database query. The budget only works when somebody notices it moved.
Third parties are product decisions
Analytics, chat, scheduling, consent, experimentation, and advertising scripts can consume more execution time than the page itself. They also create privacy, security, and resilience dependencies. “Marketing needs it” is not enough detail. Name the decision it supports, the person who reads the output, and what would cause the script to be removed.
Start with zero and add the smallest useful measurement. A contact conversion may need a page view and a successful-submit event, not a replay of every pointer movement. If a third party blocks the main experience or changes layout late, it has exceeded its place regardless of how little code the team wrote themselves.
Test the page people will receive
Development mode is noisy and a designer’s laptop is forgiving. Test a production build with caching both cold and warm, CPU and network throttling, representative content, and the consent or third-party state that will exist after launch. Check at least the homepage, the heaviest case or product page, and the conversion path.
Lab tests make regressions reproducible. Field data shows what real devices and networks experience. Use both when traffic allows it, but do not wait for a large dataset before fixing an obvious oversized image or long main-thread task. Record the test profile beside the result; a number without its conditions is marketing, not measurement.
Hold the budget after launch
Performance decays through reasonable individual additions: one campaign tag, one new font weight, one richer embed. Set automated size checks where possible and make the performance budget part of acceptance for new work. When the budget must grow, remove something or write down why the new cost is worth it.
Performance is part of our product reset, not a polish phase. The work includes products where live data, payments, and application code still have to produce a calm front end. If a page looks fast in the file but fails in the browser,send us the URL and the constraint.