Web Performance

Website performance and Core Web Vitals: an engineering budget

Treating LCP, INP and CLS as build-time budgets rather than a post-launch cleanup exercise.

Website performance is almost never lost in one place. It leaks: a font here, an analytics tag there, a hero image nobody resized, a component library imported whole for one button. By launch the site is slow and no single decision is to blame.

The fix is not a post-launch optimisation sprint. It is a budget agreed during design and enforced during the build.

What the three metrics actually measure

  • Largest Contentful Paint (LCP) — when the main content of the page becomes visible. In practice this is almost always the hero image or the headline.
  • Interaction to Next Paint (INP) — how quickly the page responds to input. Poor INP nearly always means the main thread is busy with JavaScript.
  • Cumulative Layout Shift (CLS) — how much content moves during load. Usually caused by images without dimensions, late-loading fonts, or injected banners.

They are field metrics, gathered from real visitors on real devices and connections. That distinction matters: a lab score on a fast laptop can look excellent while the field data from mid-range phones on mobile networks tells a different story.

Setting the budget before design

A performance budget is a small set of numbers agreed before layouts are drawn, because the expensive decisions are made in design, not in code. A full-bleed video hero is a performance decision. So is a carousel of high-resolution photography, and so is a headline in a font that has to be downloaded before anything is legible.

A workable starting budget for a marketing site:

  • JavaScript: under 150 KB compressed on the critical path
  • CSS: a single stylesheet, under 40 KB compressed
  • Hero image: under 150 KB, served in a modern format at the displayed size
  • Fonts: two families maximum, self-hosted, subset, preloaded
  • Third-party scripts: an explicit, reviewed list — not an open door

Fixing LCP: it is usually the hero

LCP has three components — time to first byte, resource load time, and render delay. Attack them in that order.

  • Serve HTML from a CDN edge so first byte arrives quickly regardless of visitor location.
  • Give the LCP image an explicit fetchpriority="high" and never lazy-load it. Lazy-loading the hero is one of the most common self-inflicted performance wounds.
  • Serve responsive sizes with srcset in AVIF or WebP so a phone does not download a desktop-sized image.
  • Preload the primary font and use font-display: swap so text is legible before the webfont arrives.

If the LCP element is text rather than an image, the font is usually the bottleneck, and self-hosting a subset removes both the DNS and connection cost of a third-party font host.

Fixing INP: ship less JavaScript

INP problems are main-thread problems. The most effective fix is not optimising the JavaScript you ship — it is shipping less of it.

  • Ask whether a component needs a framework at all. A navigation toggle, an accordion and a scroll reveal are a few dozen lines of vanilla JavaScript.
  • Defer anything not needed for first interaction, and load heavy features only when the user reaches them.
  • Break long tasks up so the browser can respond to input between chunks.
  • Use CSS for animation wherever possible; transforms and opacity run off the main thread.

Third-party tags deserve particular scrutiny. Each one is code you did not write, running on your main thread, changing without your knowledge. Audit the list; most sites are carrying tags nobody has looked at in a year.

Fixing CLS: reserve the space

Layout shift is the most straightforward of the three to eliminate, and the most commonly ignored.

  • Set width and height attributes on every image so the browser reserves the box before the file arrives.
  • Reserve space for anything injected after load — banners, embeds, consent notices.
  • Match fallback and webfont metrics so the swap does not reflow the paragraph.
  • Never insert content above existing content once the page has rendered.

Keeping the score after launch

Performance regresses the same way it was lost the first time — one small addition at a time. The defence is automation: run a performance check in the deployment pipeline and fail the build when the budget is exceeded. A failing build is an argument that resolves itself; a monthly report is an argument that recurs.

This is how we build at X3von — the budget is part of the specification, and the pipeline enforces it. Our website development service covers the approach in more detail.

X3von Engineering
Engineering team, X3von Technologies

Related reading

Service: Website Development  ·  All insights

Start a project

Let’s build something exceptional.

Turn your idea, business challenge or digital transformation goal into a scalable technology solution with X3von. Share the brief and an engineering advisor will reply within one business day.

Chat on WhatsApp