Priority tips for optimizing Core Web Vitals from the Chrome team

How to get maximum bang for your buck with Core Web Vitals optimization.

Core Web Vitals.

Chrome’s web dev team has spent a year figuring out their top web optimization tips for the Google's Core Web Vitals. They wanted to identify a set of measures which would give the most bang for your buck, and which most developers were likely to adopt.

The team recognised that it’s unrealistic for most sites to implement the full set of recommendations which Google has given over the years. They considered not just the technical merits of recommendations, but whether these were measures sites would have the time or resources to implement.

Their aim was to chart a path through to a more realistic set of effective measures.

Here’s how they defined their focus:

  • Recommendations we believe will have the largest real-world impact.
  • Recommendations that are relevant and applicable to most sites.
  • Recommendations that are realistic for most developers to implement.

They’ve now shared their findings. It’s a useful read for anyone unsure what to prioritize, or overwhelmed by the sheer volume of recommendations available. 

LCP (Largest Contentful Paint)

This is a measure of load performance and it’s the one Google says most sites struggle with, of the three Core Web Vitals metrics. It says only around 50% of websites meet the recommended threshold.

Here are the recommendations:

Make sure the LCP resource is findable from the HTML source

72% of mobile pages have an image as their LCP element, which means to optimize LCP, sites need to make sure the images can load quickly. 39% of these images had source urls which were not discoverable from the HTML document source. This means the browser was not able to discover them quickly and start loading straight away.

Tips to make sure your LCP image is discoverable from the HTML source:

  • Load the image using an <img> element with the src or srcset attribute.
  • Prefer server-side rendering (SSR) over client-side rendering (CSR). (CSR needs JavaScript to run before the image can be discovered)
  • If your image needs to be referenced from an external CSS or JS file, you can still include it in the HTML source via a <link rel="preload"> tag.

Make sure the LCP resource is prioritized

  • Tell the browser what the highest priority is by adding fetchpriority="high"  to the <img> tag of your LCP image. 
  • Be cafeful not to set loading="lazy" to the <img> tag of your LCP image, as this will deprioritize the image and delay the start of it loading.
  • Where possible, defer non-critical resources.

Use a CDN (content delivery network) to deliver the best TTFB (Time to First Byte)

The best way to reduce TTFB is to serve your content as geographically close to your users as you can, and cache the content to it can be served again quickly. The Chrome team says  the best way to achieve these two steps is to use a CDN.

CLS (Cumulative Layout Shift)

This is a measure of on-page visual stability. Google says despite improvement, around 25% of sites fail to meet the recommended threshold.

Here are the recommendations:

Set explicit sizes on content loaded from the page

The best way to mitigate layout shifts (existing content moving after other content finishes loading) to reserve any required space in advance by explicitly setting width and height attributes.  Without this browsers initially set a default height of 0px, so there may be a layout shift when the image is fully loaded.

CLS may also be caused by other content eg third-party ads or embedded video, that loads after the page is initially rendered. Use the aspect-ratio shift in CSS to explicitly provide an aspect ratio to images as well as non-image elements. This lets you set a dynamic width (eg based on screen size) and the browser then automatically calculates the appropriate height.

If you don’t know the exact size of dynamic content set a min-height, which will still allow the container to grow to the final content height if needed, just reducing the level of growth from the full amount.

Make sure pages are eligible for bfcache (back/forward cache)

The back/forward cache is used by browsers to instantly load a page from earlier or later in the browser history directly from a memory snapshot. It’s one of the biggest gains you can make in CLS, but will generally also improve other Core Web Vitals.

It’s a significant browser-level optimisation. You should check your pages are eligible, and if not work on the reasons why. Use the Chrome bfcache tester in Dev Tools.

Avoid animations or transitions which can affect layout shift

Animated content such as cookie banners or notifications that slide in are another common source of layout shifts. It’s a particular issue when banners push other content out of the way, but even when the don’t, animating them can still impact CLS.

As a general rule, don’t animate or transition any CSS property that requires the browser to update the page layout, unless it’s in response to a user action such as a tap or key press. Use the CSS transform property for transitions and animations wherever possible.

FID (First Input Delay)

This is the measure of a page’s responsiveness to user interactions. Google says most websites currently score very well on this metric, but there's still a lot of opportunity for improvement.

Google’s new Interaction to Next Paint (INP) metric is a possible successor to FID. The recommendations hold equally well for both and Google says:

Given that sites perform worse on INP than FID, especially on mobile, we encourage developers to seriously consider these responsiveness recommendations, despite having "good" FID.

Here are the recommendations:

Avoid long tasks or break them up

Tasks are any piece of discrete work the browser does, for example rendering, layout, parsing and so on. Long tasks are those that exceed 50 milliseconds. They then block the main thread making it harder for the browser to respond quickly to user inputs.

You can help the main thread by breaking up long tasks into smaller ones, and you can achieve this by yielding to the main thread often, so critical user-visible work can occur more quickly.

Avoid unnecessary JavaScript

Too much JavaScript results in tasks competing for the main thread’s attention and this can definitely affect your website’s responsiveness.

Use the coverage tool in Chrome DevTools to find unnecessary and unused code. Decreasing the size of resources needed during startup will lead to a smoother user experience. Sometimes unused code wasn’t executed during startup but it still needed for some future functionality. Move this code to a separate bundle using code splitting.

If you use a tag manager make sure your tags are optimized and clear out older tags with unused code.

Avoid large rendering updates

Rendering large updates can impede your website’s ability to respond to user inputs.

Optimising rendering isn’t straightforward, but Google says there are steps you can take to ensure your rendering updates don’t morph into long tasks:

The full guide to recommended measures is available on Google’s web.dev blog.