How to improve the Core Web Vitals of a front-end app

  • vuetelemetry
  • Guides
  • 7 min read

Core Web Vitals measure how a page feels to real users — loading, responsiveness and stability. Here is what they are and concrete ways to improve them, SPA included.

Core Web Vitals are a set of metrics defined by Google to capture how a page actually feels to use, as opposed to how fast it is in the abstract. They focus on three real-world experiences: how quickly the main content appears, how stable the layout is while it loads, and how promptly the page responds to your input. Because they are measured on real visits, they reward pages that feel good rather than pages that merely score well in a lab.

LCP, CLS and INP explained

A person in a blue sweater working on an iMac that displays HTML and CSS source code.
A person in a blue sweater working on an iMac that displays HTML and CSS source code.

The first metric, Largest Contentful Paint, measures how long it takes for the largest visible element — usually a hero image, heading or block of text — to render. It is a proxy for "when does the page look loaded?" A slow LCP means visitors stare at a blank or half-built screen, and it is one of the most common reasons a page feels sluggish even when it is technically functional.

The second, Cumulative Layout Shift, measures unexpected movement of content as the page loads. You have felt a bad CLS score whenever a button jumps just as you go to tap it, because an image or ad loaded above it and shoved everything down. It quantifies that jarring instability, and improving it is largely about reserving space for content before it arrives.

The third, Interaction to Next Paint, measures responsiveness — how quickly the page reacts visibly after you click, tap or type. A poor INP means the interface feels laggy and unresponsive, often because the browser’s main thread is busy running JavaScript when you try to interact. For script-heavy apps, this is frequently the hardest of the three to get right.

Fixing each metric

Improving LCP usually comes down to delivering the important content sooner. Optimise and properly size images, serve them in modern formats, and use the loading and priority hints the platform provides; ensure your server or CDN responds quickly; and avoid blocking the initial render with unnecessary scripts and stylesheets. The goal is for the most important pixels to arrive as early as possible.

  • LCP — how fast the main content appears; optimise images and server response
  • CLS — layout stability; reserve space for images, embeds and fonts
  • INP — responsiveness; reduce and split main-thread JavaScript
  • SPAs: code-split, lazy-load, trim bundles; add SSR for a fast first paint
  • Measure with real field data (CrUX), not just a single lab run

Fixing CLS is mostly about reserving space ahead of time. Always set explicit width and height (or an aspect ratio) on images and embeds so the browser leaves room for them before they load, avoid inserting content above what the user is already reading, and be careful with web fonts so text does not reflow when the custom font swaps in. These are small, mechanical changes with an outsized effect on how stable a page feels.

Improving INP means doing less work on the main thread at the moment of interaction. Break up long-running JavaScript tasks, defer or remove scripts that are not needed immediately, and be disciplined about third-party code, which is a frequent and invisible cause of unresponsiveness. The less the browser has to do when a user clicks, the faster it can paint the result.

Special care for single-page apps

Single-page applications need particular attention here, because their strengths and their Core Web Vitals risks come from the same source. The JavaScript bundle that makes navigation feel instant can also delay the first paint and block interactions if it grows too large. Code-splitting so each route loads only what it needs, lazy-loading heavy components, and trimming dependencies are the levers that keep an SPA both fluid and fast to load.

Server-side rendering and static generation help SPAs on exactly these metrics. By sending real, rendered content on the first response — via Nuxt, Next.js or a static build — you give the user a fast LCP instead of a blank screen waiting for scripts. The app then hydrates into its interactive form, so you keep the smooth navigation while fixing the heavy-first-load problem that hurts Vitals.

Server-side rendering and static generation help SPAs on exactly these metrics. By sending real, rendered content on the first response — via Nuxt, Next.js or a static build — you give the user a fast LCP instead of a blank screen waiting for scripts. The app then hydrates into its interactive form, so you keep the smooth navigation while fixing the heavy-first-load problem that hurts Vitals.

— vuetelemetry

Measure with real field data

Finally, measure with real data, not just a one-off lab test. Tools like PageSpeed Insights and Lighthouse are useful for diagnosis, but field data from real users — through the Chrome User Experience Report or your own monitoring — tells you what visitors actually experience across devices and networks. Improving Core Web Vitals is an ongoing habit of measuring, fixing the worst offender, and measuring again, rather than a box you tick once.

Related stack