Back to topics

Core Web Vitals

Consists of three metrics: LCP + INP + CLS

Press F12 β†’ Performance tab to see these three metrics.

LCP (Largest Contentful Paint)

πŸ“Ž Documentation

Refers to the time it takes for the largest visible element in the viewport (usually a large image, video, or large block of text) to fully render.

How it works

The browser continuously monitors elements appearing on the screen, constantly updating which one is the "current largest", until the user starts interacting. Once the user interacts (click, scroll, key press), or the page is hidden, the browser stops searching and records the render time of the last determined largest element as the LCP time.

Common optimization strategies

  • Compress large images and use them in friendlier formats (e.g., WebP)

  • Increase download priority (fetchpriority="high"). Regarding download priority: MDN Documentation

  • Host images on a CDN

  • Consider using SSR β€” to display images or other content immediately, otherwise you need to wait for JS to load before rendering

  • The preloading strategy will be explained in detail later.

INP (Interaction to Next Paint)

πŸ“Ž Documentation

Refers to the delay between a user interacting with the page (clicking a button, typing text, etc.) and the browser providing visual feedback via the next frame's paint.

How it works

INP monitors all interactions during the page's lifecycle and takes the longest interaction time as the final score.

INP primarily consists of three parts:

  1. Input delay β€” JavaScript is single-threaded; the main thread may have other tasks that prevent immediate response to an action. For example, when clicking a button, the time from the user's finger pressing down to the actual start of the JS event callback function is the input delay.

  2. Processing time β€” The time required to execute the event callback function.

  3. Presentation delay β€” After the code executes, the browser needs to recalculate styles, layout, and paint pixels to the screen. This period is called presentation delay.

If you've learned about performance metrics before, you may have heard of FID (First Input Delay).
INP officially replaced the old metric FID in March 2024. INP is stricter than FID β€” it monitors all interaction delays throughout the page's entire lifecycle, not just the first.

CLS (Cumulative Layout Shift)

πŸ“Ž Documentation

Used to measure visual stability.

layout shift score = impact fraction Γ— distance fraction

Simply put: the larger the element, and the farther it is displaced during layout, the worse the metric.

Common causes and optimization

  1. Image elements without defined dimensions β€” Images load slowly, and when they load, the entire document shifts. If dimensions are hard to determine, you can write:

.card-image {
  width: 100%;
  aspect-ratio: 16 / 9; /* lock 16:9 aspect ratio */
  object-fit: cover;    /* ensure image doesn't stretch */
}

The browser always reserves height based on the aspect ratio, avoiding document shift.

  1. Dynamically inserted content β€” For example, some websites insert Google AdSense for profit, which causes element shift when the ad is inserted. The correct approach is to reserve a container with a set height for the ad (skeleton screen).

  2. Incorrect use of animations β€” Using margin-top or top/left for animations triggers reflow on every displacement, causing the browser to recalculate layout each frame and thus causing shift. The correct approach is to use transform: translateY().