Performance work fails when it begins with:
“We will optimize at the end.”
By the end, the hero image is already part of the campaign, the chat widget belongs to sales, the animation belongs to the brand, and the JavaScript belongs to six feature teams.
Nobody owns the total page.
A performance budget creates ownership before the page becomes expensive.
Field data is the outcome
Core Web Vitals are field metrics evaluated from real user visits.
The current “good” thresholds are:
- LCP at or below 2.5 seconds;
- INP at or below 200 milliseconds;
- CLS at or below 0.1;
measured at the 75th percentile.
Lab tools help diagnose.
They do not prove the field outcome.
The official Core Web Vitals threshold guide is the reference I use for current definitions.
Budget the experience, not one score
I set budgets around causes:
- initial document response;
- primary visual asset;
- font files and variants;
- route JavaScript;
- hydration scope;
- third-party scripts;
- long tasks;
- layout movement;
- interaction feedback;
- below-the-fold loading.
The exact byte numbers depend on the product.
The ownership model does not.
Give LCP one clear candidate
The page should know which element is likely to be its largest meaningful content.
For a hero image:
- use correct dimensions;
- serve responsive sizes;
- avoid a decorative file far larger than its display;
- give the browser an early path to the resource;
- do not lazy-load the primary visual;
- avoid covering it with late-loading layers.
For an LCP heading or text block:
- load critical fonts carefully;
- avoid invisible text;
- avoid client-only rendering;
- keep server response healthy.
Five “priority” images are not a priority system.
Reserve layout space
CLS often comes from missing ownership:
- image without dimensions;
- ad or embed without a slot;
- font swap changing geometry;
- late banner;
- validation message pushing actions;
- animation that changes layout.
Reserve the final geometry when possible.
For dynamic messages, design a stable place or a transition that does not make the user chase the interface.
JavaScript must justify itself
Every Client Component, provider, analytics script, widget, and animation adds work.
I review:
- Does it need to run on initial load?
- Does it need the whole library?
- Can the server render the content?
- Can the interaction stay in a smaller island?
- Can the script wait for consent or intent?
- Does it block the main task?
- Is it still used?
Removing unused behavior is often safer than micro-optimizing it.
Protect interaction latency
INP problems are usually ownership problems too.
A click triggers:
- validation;
- state updates;
- filtering;
- layout;
- analytics;
- animation;
- network work;
- rerenders.
I keep the immediate feedback cheap and move non-urgent work away from the critical interaction.
Long lists need bounded rendering.
Heavy calculations may need a worker, server computation, or a different interaction.
Third parties need a business owner
No third-party script is “free.”
For each one, document:
- purpose;
- owner;
- pages;
- load timing;
- consent requirement;
- performance cost;
- failure behavior;
- removal condition.
If nobody can explain why a script exists, it should not receive permanent page budget.
Performance is part of acceptance
I add checks to the feature:
- image dimensions and responsive source;
- no unexpected layout shift;
- keyboard interaction remains responsive;
- loading and error states are bounded;
- reduced motion is respected;
- route JavaScript change is understood;
- critical user path is measured after release.
This is better than a final “performance ticket” with no authority over the feature.
Budget changes need a tradeoff
Sometimes a heavier asset is worth it.
A product demo video may improve understanding. A payment provider may be essential. Accessibility behavior may require code.
The budget is not a ban.
It makes the tradeoff visible:
- what value is added;
- what cost is added;
- what can be removed;
- how the outcome will be measured.
My release rule
I do not claim a performance win from code inspection alone.
I report:
- static risks addressed;
- lab checks if authorized and run;
- field data if available;
- representative devices and routes;
- what remains unknown.
That honesty is part of performance engineering.
For server/client JavaScript ownership, read how I draw Next.js boundaries. For search launch checks, read my technical SEO checklist.
If a page became slow one feature at a time, send me the route, primary task, and newest heavy dependency.
- #Web Performance
- #Core Web Vitals
- #Next.js
- #Performance Budget
- #Frontend

Continue reading
Related field notes on engineering, SaaS, freelancing, and building dependable products.