|

Improve Core Web Vitals: 9 Tips for 2023 Success

TL;DR;

Discover 9 tips to improve core web vitals and boost your site’s performance, as shared in a helpful video by the Chrome team, covering metrics like LCP, CLS, and FID/INP.

  • Tip 1: LCP โ€” Ensure image sources are easily found
  • Tip 2: LCP – Use fetchpriority on images or preloads
  • Tip 3: LCP – Serve static assets with a CDN
  • Tip 4: CLS – Set specific sizes on content
  • Tip 5: CLS – Keep bfcache enabled on pages
  • Tip 6: CLS – Avoid CSS layout-inducing animations/transitions
  • Tip 7: FID/INT – Avoid or break up long tasks with zero-millisecond delay timeouts
  • Tip 8: FID/INT – Remove all unused JavaScript
  • Tip 9: FID/INT – Avoid large rendering updates & make use of the CSS content-visibility property

9 Tips to Improve Core Web Vitals

Shoutout to my awesome colleague, Michael from 10up, who shared a fantastic video packed with 9 effective ways to supercharge your website’s core vitals. ๐Ÿ™Œ With countless articles floating around, it’s easy to feel overwhelmed. But fear not, because this Chrome team video has got your back! They’ve made it a breeze to seize quick wins and enhance your site’s performance. ๐Ÿ’ช

In this article, we’ll dive into three key metrics that can transform your site’s user experience. Say hello to LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift), and FID/INP (First Input Delay/Interaction to Next Paint). We’ll unravel the mystery behind these terms and reveal practical tips on how to conquer them like a pro. ๐ŸŽฏ

So, grab your favorite beverage, sit back, and let’s embark on this adventure to unlock the secrets of improved core web vitals! ๐Ÿš€๐Ÿ”

Improve Web Vitals by Boosting LCP

Did you know that as per CrUX data from February 2023, a remarkable 56.3% of sites have achieved excellent LCP scores? Impressive strides have been made, but the journey to optimize core web vitals doesn’t end there. While 73.1% of sites excel in CLS and 95.3% shine in FID, there’s still an opportunity to improve LCP and supercharge your site’s performance. ๐Ÿ“Š๐Ÿ’ช

Pass Rates of Each Core Web Vital

56.3%

Sites with good LCP

73.1%

Sites with good CLS

95.3%

Sites with good FID

(Source: CrUX data – February 2023)

One crucial factor affecting LCP performance is the handling of image resources. Surprisingly, it’s not always the download time that poses the biggest challenge. To improve core web vitals, one of the most effective steps you can take is to ensure the LCP resource is seamlessly discoverable right from the HTML source. ๐Ÿ•ต๏ธโ€โ™€๏ธ๐Ÿ’ก

Improve Core Web Vitals: LCP Content Types
Source: Google Chrome Developers

Biggest win for Improving Core Web Vitals: LCP

When it comes to optimizing core web vitals, one of the most powerful techniques you can employ is ensuring that your image sources are easily discoverable within the static HTML. This simple yet effective step enables the browser’s preload scanner to swiftly locate and load these images at the earliest opportunity, enhancing your site’s overall performance. ๐Ÿ“Š๐Ÿ’ช

<!-- Background images are not discoverable -->
<div style="background-image: url(image-url.jpg)">

<!-- img srcs which are loaded using JavaScript are not discoverable -->
<img data-src="image-url.jpg" alt="..." />
<img ng-src="{{ image-url.jpg }}" alt="..." />

<!-- Lazy loaded <img> elements are ignored by the preload scanner -->
<img src="image-url.jpg" alt="..." loading="lazy" />

Keep an eye out for common gotchas that hinder the discoverability of LCP images, such as background images, client-side rendering, and lazy loading. These practices often raise red flags, signaling potential issues with image discoverability. The solution usually involves embracing the tried-and-true image element or, if necessary, incorporating a preload link in the HTML to reference the resource. By adopting either of these methods, you empower the preload scanner to detect the image resource and promptly queue it for fetching by the browser. ๐Ÿ•ต๏ธโ€โ™€๏ธ๐Ÿ’ก

The Fix
<!-- An <img> element is easily discoverable -->
<img src="image-url.jpg" alt="..." />

<!-- Alternatively, preloading the image makes it discoverable -->
<link rel="preload" href="image-url.jpg" as="image" />

To identify issues, utilize the loading waterfall feature in Chrome DevTools. If you notice a significant delay between HTML processing and the LCP image request, chances are you’re facing a discoverability hurdle. By including the image directly in the HTML using an image element or preload, you ensure instant discovery, resulting in faster downloading. While a small loading gap may still persist, we’ll delve into addressing that in the upcoming sections. ๐Ÿš€

Chrome Waterfall for Core Web Vitals
Source: Google Chrome Developers

Use the Fetch Priority API for an Easy Win

While ensuring the discoverability of your images is crucial for optimal performance, it’s equally important to maximize their fetching speed. Traditionally, browsers prioritize render-blocking content like CSS and synchronous JavaScript over images, leading to potential delays in fetching. But fear not, because we have a game-changing solution: the Fetch Priority API. ๐Ÿš€

By simply adding the fetchpriority="high" attribute to your image or preload LCP element, you can flag the resource as high importance. This grants the browser the power to initiate earlier and higher-priority downloads, significantly impacting your LCP time. While this API is already available in Chromium-based browsers, Safari and Firefox are actively working on their implementations. Remember, this attribute acts as a progressive enhancement, gracefully ignored by non-supporting browsers. ๐Ÿ’ช

<!-- Add fetchpriority to imporant image elements -->
<img src="myurl.jpg" alt="..." fetchpriority="high" />

<!-- The fetchpriority attribute can also be used on preloads -->
<link rel="preload" href="myurl.jpg" as="image" fetchpriority="high" />

Returning to our earlier example, we successfully tackled the discoverability hurdle. However, there was still a noticeable delay until the image was requested and began downloading. Enter fetchpriority, where the delay is minimized, and the image starts downloading almost instantly upon discovery. This remarkable outcome is precisely what we desire for LCP images. ๐ŸŒŸ

fetchpriority example for improving core web vitals
Source: Google Chrome Developers

Additionally, you have the power to deprioritize non-critical resources using techniques like fetchpriority="low" or lazy loading, ensuring they’re fetched only when necessary. This strategic deprioritization allows the browser to concentrate on vital resources, such as your LCP element. Remember, though, it’s essential to avoid using these deprioritizing techniques on the LCP images themselves. ๐Ÿ˜Š

<!-- Use fetchpriority="low" for lower priority images that the -->
<!-- browser may otherwise consider in, or near, the viewport -->
<ul class="carousel">
  <li><img src="img/carousel-1.jpg" fetchpriority="high" /></li>
  <li><img src="img/carousel-2.jpg" fetchpriority="low" /></li>
  <li><img src="img/carousel-3.jpg" fetchpriority="low" /></li>
  <li><img src="img/carousel-4.jpg" fetchpriority="low" /></li>
</ul>

If you’re utilizing a JavaScript framework, the Chrome Aurora team has collaborated on image components that embody best practices. Angular and Next.js components already support fetchpriority, while the Nuxt image component is actively being updated to join the league. The Google Chrome team also extends its reach to other platforms. For WordPress users, the official WordPress Performance Lab plugin now features the new fetchpriority module developed in partnership with the WordPress code performance team. ๐Ÿ™Œ

The first two LCP recommendations focused on HTML structuring for discoverability and download prioritization. However, keep in mind that all of this hinges on having the HTML in the first place. So, let’s continue our journey as we uncover more insights and techniques to revolutionize your core web vitals! โšก๐Ÿ”

CDNs are King to Improve Core Web Vitals

Did you know that the browser eagerly awaits the first byte of the initial HTML document response before loading any sub-resources? The faster the browser receives those crucial first bytes, the quicker it can start processing, unleashing a chain reaction of improved performance. So, how can you reduce TTFB and kickstart this vital process? Let’s explore two powerful strategies: proximity and caching. ๐Ÿ’ก

First, to minimize TTFB, ensure that your content is served as close to your users as possible, reducing the distance between servers and users. Secondly, leverage content caching, allowing frequently requested content to be served rapidly. How can you achieve both? The answer lies in a Content Delivery Network (CDN). ๐ŸŒ

LCP to Improve Core Web Vitals
Source: Google Chrome Developers

CDNs are globally distributed server networks strategically positioned to connect with your users. By shortening the “last mile,” often the slowest part of the journey, CDNs minimize the impact of latency. Additionally, CDNs enable efficient content caching at these edge nodes, further slashing load times. Even when the journey requires reaching back to your origin server, CDNs are designed to expedite the process. It’s a win-win situation! ๐Ÿš€

While developers commonly use CDNs for hosting static assets like CSS, JavaScript, images, and videos, serving HTML over CDN can unlock even greater benefits. Surprisingly, according to the Web Almanac, only 29% of HTML document requests are served via a CDN. If you’re not among these savvy individuals, there is a significant opportunity for you to claim additional savings and turbocharge your core web vitals. ๐Ÿ”ฅ

Source: Web Almanac

So, why wait? Embrace the power of CDN optimization and take your site’s performance to new heights. Join the ranks of those who have harnessed this powerful technique, and let your users experience lightning-fast page loads.

Simple CLS Methods to Improve Web Vitals

Let’s dive into the fascinating world of Cumulative Layout Shift (CLS), the measure of a web page’s visual stability. Picture this: content constantly shifting and jumping as new elements load. While CLS has made significant strides since 2020, it’s surprising to learn that approximately a quarter of websites still fall short of the recommended threshold. This signifies a tremendous opportunity for countless sites to enhance their user experience. ๐Ÿ’ก๐ŸŒ

Set Explicit Sizes on Content

When it comes to Cumulative Layout Shift (CLS), the first recommendation is to ensure that content is explicitly sized, allowing the browser to render it accurately from the get-go. While we often emphasize providing width and height dimensions for images, which remains a leading cause of CLS, it’s essential not to overlook other content types. Here, CSS becomes your trusted ally. ๐Ÿ’ช๐ŸŽจ

<!-- An image without dimensions will cause CLS -->
<img src="myurl.jpg" alt="..." />

<!-- Explicitly setting width and height -->
<img src="myurl.jpg" alt="..." width="400" height="200" />

With the introduction of the relatively new aspect-ratio property, you can unlock responsive possibilities beyond just images. Imagine videos and other dynamic content adapting effortlessly, setting the appropriate height based on the rendered width. This ensures a seamless browsing experience and minimizes the risk of CLS.

/* Example for default videos to 16/9 aspect ratio */
video {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}

But let’s not stop there! Another technique at your disposal is leveraging min-height, specifically for accommodating dynamic content like advertisements. By reserving a minimum space, even when the exact height is uncertain, you can significantly reduce the impact of CLS. ๐Ÿ’ก๐ŸŒ

CLS min-height example
Source: Google Chrome Developers

Don’t Disable bfcache (Back/Forward Cache)

Last year witnessed a significant boost in Cumulative Layout Shift (CLS) with the introduction of the back/forward cache, or bfcache, in Chrome (while Safari and Firefox had already embraced this feature for some time). When a page loads, additional content like images and ads may contribute to CLS. While it’s ideal to minimize such shifts from the very beginning, there’s good news: you can prevent CLS when users navigate back to a page. Let’s dive into the incredible benefits of the bfcache and how it transforms the user experience. ๐Ÿ’ก๐ŸŒ

The bfcache acts as a memory storage that holds a complete snapshot of a fully rendered page for a brief period after users navigate away. When they return to the page, the snapshot is seamlessly restored. Similarly, if users move forward again, the snapshot can be swiftly retrieved. This eliminates any CLS that would occur if the page were to be re-rendered from scratch. The bfcache is enabled by default, requiring no additional configuration.

However, certain APIs may interfere with the bfcache‘s usage, preventing the browser from utilizing this performance-boosting feature. To ensure you don’t miss out on this free optimization, it’s crucial to test your page’s bfcache eligibility. Fortunately, Chrome DevTools offers a handy tool that tests whether the bfcache was employed by navigating away and back, providing detailed explanations if it couldn’t be utilized. Additionally, Lighthouse 10 introduces an audit that performs the same eligibility test and offers insightful explanations if a page is deemed ineligible. ๐Ÿš€

bfcache for Core Web Vitals
Source: Google Chrome Developers

But wait, there’s more! They also provide the notRestoredReasons API, empowering you to identify blocking regions in the field and report them back to your analytics. As part of the Chrome team’s ongoing efforts to enhance web browsing speed, the bfcache is just one element of a series of instant page navigation improvements. Keep an eye out for other advancements, such as pre-fetching and pre-rendering, which can further optimize your Core Web Vitals and revolutionize the way users experience your site. โšก๐Ÿ”

Avoid Layout-Inducing Animations/Transitions

When it comes to handling animations and transitions, the final recommendation for Cumulative Layout Shift (CLS) optimization is here to revolutionize your Core Web Vitals. ๐Ÿš€

We often encounter animations that move content, such as cookie banners or notification banners sliding in from the top or bottom. However, the coding of these animations can significantly impact their performance and whether they contribute to CLS. Let’s dive into the details! ๐Ÿ’ก

Animations that induce layout shifts require the browser to recalculate the page layout, resulting in more work. Even absolute positioned elements, though removed from the normal document flow, can cause layout shifts. For instance, using top or left to move content may trigger a layout shift, even if it doesn’t impact surrounding elements. The shifting content itself has the potential to affect other components, thereby counting towards CLS. However, there’s an alternative that offers both improved performance and no impact on CLS. ๐ŸŒŸ

Don’t Do This
/* Don't animate top, left, bottom, or right */
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease;
}

@keyframes move {
  0% {
    top: calc(90vh - 160px);
  }
}
Do This
@keyframes move {
  0% {
    transform: translateY(calc(90vh - 160px));
  }
}

Enter translate, a composited animation technique that operates in the compositor layer rather than altering the browser’s layout processing. Animations implemented with translate don’t shift the content, resulting in reduced browser workload and zero impact on other elements. This composited approach is widely supported and serves as an ideal replacement for animations that use top or left. Always prioritize composited animations like transform over non-composite alternatives to ensure optimal CLS performance. To assist in identifying such animations, Lighthouse offers a dedicated audit. ๐Ÿ”

Source: Google Chrome Developers
Animations Handled by Composer
transform: translate (npx, npx);
transform: scale(n);
transform: rotate(ndeg);
transform: skew (X|Y) (ndeg);
transform: matrix (3d) (...);
transform: opacity: 0...1;

So, let’s bid farewell to layout-inducing animations and embrace the power of composited transformations. By doing so, you’ll not only optimize your CLS but also create smoother, visually pleasing experiences for your users.

Using VSCode? Check out the css-triggers extension by Kiss Tamรกs. It provides inline decoration to CSS properties, helping you identify their costs and determine if they are composited.

FID / INP Tactis to Improve Core Web Vitals

As we reach the final set of recommendations, get ready to supercharge both the First Input Delay (FID) and the Interaction to Next Paint (INP) metrics, all while embracing the power of responsiveness. ๐Ÿš€

The key to achieving stellar performance lies in avoiding any blockages on the main thread, as this prevents the browser from promptly responding to user input. By prioritizing responsiveness, we create an optimized environment that maximizes user engagement and interaction. ๐Ÿ’ก๐Ÿ’ช

Avoid or Break Up Long Tasks

Our first recommendation is a game-changer when it comes to improving Core Web Vitals: identifying and breaking up long tasks. By giving the browser some breathing room, we enable it to swiftly respond to user input, revolutionizing the browsing experience. ๐Ÿ’ช๐ŸŒ

Chrome DevTools and Lighthouse come to the rescue, helping us identify those critical long tasks that take 50 milliseconds or more. While it may seem insignificant, in browser terms, it can make all the difference between a site feeling instantly responsive or frustratingly sluggish. JavaScript, being single-threaded and naturally resource-hungry, tends to cling onto the CPU as long as possible until it exhausts its processing capabilities. ๐Ÿ˜ฎ

But fear not! The key lies in introducing those crucial breaks in your code. By strategically inserting timeouts with zero-millisecond delays, you can assign non-critical work to new tasks that execute after any existing queued tasks. It’s a simple yet powerful technique that paves the way for improved responsiveness. Additionally, newer browser APIs like isInputPending, scheduler.postTask, and scheduler.yield offer exciting opportunities to determine when and how to yield the main thread, further optimizing long tasks.

Don’t Do
function saveSettings() {
  validateForm();
  showSpinner();
  saveToDatabase();
  updateUI();
  sendAnalytics();
}
Do This
function saveSettings() {
  // Do critical work that is user-visible:
  validateForm();
  showSpinner();
  updateUI();

  // Defer work that isn't user-visible to a seperate task:
  setTimeout(() => {
    saveToDatabase();
    sendAnalytics();
  }, 0);
}

Avoid Unnecessary JavaScript

While optimizing the JavaScript on our web pages is undeniably important, there’s an even more powerful approach: sending less JavaScript in the first place. Our insatiable thirst for adding more and more JavaScript can hinder performance, but it’s time to challenge that status quo. Let’s dive into the secrets of efficient JavaScript usage and take control of our core web vitals. ๐Ÿ’ก๐ŸŒ

Chrome DevTools offers a remarkable feature called “coverage” that reveals how much of your JavaScript code is actually executed during page load. This eye-opening analysis allows you to identify portions of code that go unused. Armed with this knowledge, you can embark on a journey of code splitting, selectively loading specific code segments when needed or during less busy browser moments. By employing code-splitting techniques, you can reduce the impact of unnecessary JavaScript, optimizing performance without sacrificing functionality. ๐ŸŒŸ๐Ÿ’ช

To further enhance this optimization process, the Aurora team has developed the Next.js script component. This powerful tool enables you to load less critical, often third-party code using various strategies that minimize their impact. Bid farewell to heavy scripts that weigh down your pages and embrace lightweight alternatives for improved performance. ๐Ÿ’ฅ

<!-- Example for beforeInteractive -->
<Script src="script.js" strategy="beforeInteractive" />

<!-- Example for afterInteractive (default) -->
<Script src="script.js" />

<!-- Example for lazyonload -->
<Script src="script.js" strategy="lazyOnLoad" />

Remember, tag managers are notorious hotspots for accumulating old and potentially unnecessary JavaScript code. Regularly auditing your tags is crucial to ensure their removal. Even if they no longer fire, they still consume valuable time and resources during downloading, parsing, and compilation. By eliminating redundant tags, you free up the browser to focus on more important tasks, optimizing its utilization. โšก๐Ÿ”

Avoid Large Rendering Updates

As we conclude our journey to enhance responsiveness, there’s one final recommendation that can work wonders for your website’s performance. Brace yourself for the secrets to avoiding large rendering updates and optimizing your Core Web Vitals. ๐Ÿ’ช๐Ÿš€

While JavaScript plays a crucial role in responsiveness, let’s not forget that the browser itself can slow down when faced with extensive rendering tasks. Large rendering updates occur when there are numerous DOM changes, either intentionally or triggered by a cascade effect where one change ripples through the entire layout. To counteract this, keeping your DOM size small is key. By minimizing the DOM’s complexity, even if cascade effects occur, they can be swiftly handled, ensuring a lightning-fast browsing experience. And yes, Lighthouse has you covered with a dedicated audit to assist in this optimization process. ๐Ÿ”๐ŸŒ

Source: Google Chrome Developers

CSS containment emerges as a game-changer in our quest for optimal rendering. By strategically separating areas within a web page, you can instruct the browser that elements in specific regions remain unaffected by changes in other areas. This efficient isolation minimizes unnecessary layout work, enabling the browser to deliver blazing-fast rendering. Additionally, content-visibility, an extension of CSS containment, allows you to skip layout and rendering entirely for off-screen content. This technique further enhances performance by prioritizing what’s visible to the user, delivering seamless interactions without wasting precious resources. ๐Ÿ’ก๐Ÿ’ฅ

/* The CSS contain property lets developers limit the scope
   of the browser's styles, layout and paint work */
contain: none;
contain: strict;
contain: content;
contain: size;
contain: inline-size;
contain: layout;
contain: style;
contain: paint;

/* The content-visibility CSS contain property allows
   Chromium-based browsers to skip layout and rendering
   completely */
content-visibility: visible;
content-visibility: hidden;
content-visibility: auto;

Lastly, exercise caution when using the requestAnimationFrame API. This powerful tool should only be employed for critical rendering work. Overusing this API can burden rendering itself, leading to sluggish performance. Optimize its usage to ensure that your rendering tasks remain efficient and responsive. โšก๐ŸŽจ


Wrapping Up

And there you have itโ€”our nine top recommendations for unleashing the full potential of your Core Web Vitals. It’s time to dive in and revolutionize your website’s responsiveness. By implementing these strategies, you’ll create an immersive browsing experience that captivates your audience. Stay tuned for more optimization techniques and witness the remarkable transformation of your web presence! ๐ŸŒŸ๐Ÿš€

Share Your Thoughts

Your email address will not be published. Required fields are marked *

Latest Articles