How to Optimize Speed and Usability for Google’s Core Web Vitals

Ingo Steinke
10 min readMar 2, 2021
GTMetrix performance analysis of ingosteinke.com

Google’s “Core Web Vitals”, Largest Contentful Paint (LCP), First Input Delay (FID), and Cumulative Layout Shift (CLS) can help us to measure and optimize web page speed, usability, and search engine visibility. Thanks to Addy Osmani and Houssein Djirdeh from Google and to everybody else for their explanations. This article is based on my original article on dev.to.

Measuring Web Performance and Usability

LCP (Largest Contentful Paint), FID (First Input Delay), CLS (Cumulative Layout Shift)

Core Web Vitals Metrics in Web Performance Tools

Web performance measuring tools, like PageSpeed Insights, Lighthouse, WebPageTest, and GTMetrix include web vitals in their metrics.

Total Blocking Time or First Input Delay?

Many web performance tools already highlight the new core web vitals. As a real user metric, First Input Delay is part of “field data” collected when monitoring actual people using your website. Test runs in a tool are not equivalent to real user data. They are rather “lab” or synthetic test results.

First input delay can not be measured in an automatic test, as there is nobody trying to input anything. But we can estimate the results by measuring a website’s total blocking time, a metric that has been used before web vitals, to measure basically the same thing without user interaction.

Popular online tools list Total Blocking Time (TBT) as a third vital metric instead of First Input Delay (FID). So we will cover that metric later on as well.

WebPageTest results for ingosteinke.com, screenshot including Speed Index, Largest Contentful Paint, Cumulative Layout Shift, and Total Blocking Time

Online Tools for Measuring Web Vitals

PageSpeed Insights, WebPageTest, GTMetrix, and Google Search Console are online tools, where you can run tests on a website that is accessible on the internet. Lighthouse, the same engine by Google that is also used for PageSpeed Insights, can be run inside the Chrome browser’s developer tools.

WebPageTest recently updated their page design as well:

WebPageTest’s new user interface

Browser Plugin and DevTools Overlay for Chrome

Addy Osmani’s Web Vitals has been a free extension for the Chrome web browser, previewing what is now built-in to chrome dev tools as the new Core Web Vitals overlay, see: https://developer.chrome.com/blog/new-in-devtools-90/#cwv

To activate the overlay, enter developer tools and open the command menu (using Control/Command + Shift + P ) and type “show render” to see the render options drawer, where you can check “core web vitals” to make the overlay appear immediately.

screenshot using the new web vitals overlay

Official Google Tools

Last but not least, I find it funny somehow to see that Google’s own sites and services perform poorly in many of their own metrics like developers.google.com gets a poor score of 30/100 in Google’s PageSpeed Insights. But then again, they might not feel the need to optimize for ranking in their own search results. At least they could optimize their web vitals.

developers.google.com gets poor score of 30/100 in Google’s PageSpeed Insights

Current versions of Lighthouse, PageSpeed Insights, and Google Search Console are based on the same engine, but the presentation and focus of their reports differ slightly. Search console only shows “field data” based on real user activity and it can help you constantly monitor your website over time.

Understanding and Optimizing Core Web Vitals

A blog post by the Chromium browser developers trying to explain the science behind web vitals concludes that “from the user’s point of view, loading a particular page doesn’t represent a natural break: they haven’t yet achieved their goal, which may make them less tolerant of delays.”

First and Largest Contentful Paint

Google’s Houssein Djirdeh elaborates that “First Contentful Paint (FCP) measures how long it takes for initial DOM content to render, but it does not capture how long it took the largest (usually more meaningful) content on the page to render.”

The Largest Contentful Paint (LCP) metric tries to measure when page-to-page navigation appears complete to a user. The recommended LCP should stay below 2.5 seconds for 75% of page loads.

How to Avoid Slow Contentful Paint

Slow Server Response Times

While you might have a problem on the server-side, there are possible solutions both on the server as well as on the client-side.

You can try to optimize your server configuration and resources, make sure it has enough CPU and memory, cache assets, use a CDN, and use resource hints (preconnect, dns-prefetch) when connecting to the server.

As most people don’t run a server of their own, make sure your provider offers either an optimized solution or else allows you to tune some of the configurations on your own. On classic shared host for PHP applications like WordPress, there is usually an Apache server that allows altering several directives by putting .htaccess files in your web root directory.

Compression and Caching for an Apache Web Server

To raise time to expire for JPG images (server-side), you can add directives like in the following examples to your Apache configuration or in an .htaccess file.

The first directive sets caching headers to allow clients (browsers and proxy servers) to use a cached version of images rather than trying to fetch the actual file on every reload.

<IfModule mod_expires.c> 
ExpiresActive on
ExpiresDefault "access plus 5 minutes"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/svg "access plus 1 month"
</IfModule>

Some servers do not send compressed files, even when they could. The following directive tells Apache to serve files in a compressed format if the client has indicated that they are able to handle it:

<IfModule mod_filter.c> 
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/x-javascript
# handle edge cases that you care about
BrowserMatch \bMSIE\s7 !no-gzip !gzip-only-text/html
</IfModule>
</IfModule>

Ilya Grigorik and Jeff Posnick have more details on how to prevent unnecessary network requests with the HTTP Cache, and Dave Gash knows what to put in your Apache server configuration.

How to Prevent Slow Resource Load Times on the Client Side

Coding your front-end sites or applications, you should try to

  • optimize, compress, and minify your assets,
  • allow them to be cached (see above),
  • preload, lazyload, and use responsive images and adaptive serving.
  • Resource hints in your HTML code can optimize how data is being downloaded. An example:
    <link rel="dns-prefetch" href="https://fonts.gstatic.com/" >
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

Drew McLellan wrote a useful article about optimizing performance with resource hints in Smashing Magazine.

Adaptive serving is a client-side technique to decide which resource to load or whether to load any resource at all, based on detected client capabilities like network speed.

The navigator object offers performance information:

  • navigator.connection.effectiveType (e.g. "4g")
  • navigator.connection.saveData (data-saver setting)
  • navigator.hardwareConcurrency (CPU core count)
  • navigator.deviceMemory (Device Memory)

Many optimizations are also offered as a service. On Netlify, you can activate CSS and JS modification as well as image compression in your site settings, and Netlify will automate those optimizations at the next deployment.

Client-Side Rendering and Hydration

You can try to use pre-rendering or server-side rendering (SSR), but this may only move the problem to a later stage. A server-rendered page may look like it can be interacted with, but it cannot respond to any user input until it is “ hydrated” (which means all the client-side JavaScript has executed). This can make Time to Interactive (TTI) worse.

Render-Blocking Assets

Split, inline, minify, and defer CSS according to its role and importance.

The most critical styles should be inlined in your HTML head, while the most optional styles can be deferred by setting the proper media type only after loading has completed:
<style>
.hero-image { background-size: cover; } /* inline critical css */
</style>
<link rel=stylesheet media=screen href="styles.css">
<link rel=stylesheet media=none onload="this.media='screen'" href="later.css">

Use the Coverage tab in your Chrome browser’s developer tools to find possibly unused CSS on your web page. Be careful to remove it, as it might be used on a separate page or only in certain situations like an error or a form submission.

Deferred loading is usually done by setting the initial media type to print, which might interfere with your actual print styles. At least modern browsers seem to load the invalid media none stylesheet nevertheless, as I found out when relaunching my own website in 2021.

You can use loadCSS to automate this technique. Other tools to help you extract critical CSS include Critical, CriticalCSS, Penthouse, and Critters (as a webpack plugin).

How to Prevent Layout Shift on Your Website

Cumulative Layout Shift (CLS) measures how frequent and severe unexpected layout shifts are on a page.” Google recommends the CLS to be less than 0.1 for 75% of page loads.

Google’s web performance expert Addy Osmani explained that “if an element suddenly moves, their eyes have to find its new position. If the user is trying to tap an element that then moves, they may end up clicking a link or ad unintentionally and significantly disrupting the user’s intended journey.

Define Image Dimensions

Setting dimensions is especially important for the content “above the fold”, which is displayed to your users before they scroll down.

Contain Your Content

Reserve fixed height containers for third-party content like ads:

<style>
.portal-billboard {
min-height: 250px; /* critical height definition */
}
</style>
<aside class="portal-billboard" aria-hidden="true">

You can use the same strategy for your own content as well. Giving your page header a minimum height will also prevent web fonts inside this header to change your header’s height and make all subsequent content shift.

No matter if you like hero headers, starting your page with a container that fills up the entire viewport height, might solve many layout shift problems that would otherwise occur unless you perfectly control your page content.

Nice Font Display without Flash of Invisible Text

Use web fonts properly (or not at all) to prevent flashing invisible or unstyled text. Unless you are lucky to find a font that closely resembles the web-safe fallback in every way, you will probably have to accept some compromise). Zach Leatherman’s article about optimizing font loading for CSS-Tricks.com will show you all the tricky issues around FOIT (invisible text), FOUT (fallback text), font-display and font annotations.

How to Improve Responsiveness

Time to Interactive is a metric that measures the time until a website has become fully interactive, when event handlers are registered for most page elements, and user interaction is processed within 50ms. As I learned from Ziemek Bućko, First Input Delay is different in that it’s able to track user input that happens before the page is fully interactive. As a purely real user metric, it cannot be simulated in a lab test. It requires user interaction in order to be measured.

How to Optimize Input Delay

Optimizing input delay comes with no surprise. The official recommendations include some JavaScript-specific tips, otherwise, keep transfer sizes small and follow the usual web performance optimization advice found on the web and inside your Lighthouse report.

  • Reduce the impact of third-party code, reduce JavaScript main thread work and overall execution time, and keep request counts low and transfer sizes small.

To trick the metric, you might be tempted to implement asynchronous event handling. That “would improve the metric but likely make the experience worse”, Philip Walton remarks in his FID guide. Try that and probably get punished by an upcoming 2022 Web Vitals update. Just don’t do it!

First Input Delay (FID) and Total Blocking Time (TBT)

Synthetic or “lab tests”, as opposed to real user metrics, cannot show the first input delay, so most display total blocking time instead. In practice, you can use TBT as an alternative metric for FID.

GTMetrix states that “Total Blocking Time (TBT) is a Lighthouse Performance metric introduced in 2020 that quantifies your page’s load responsiveness to user input. In the simplest terms, TBT measures the total amount of time your webpage was blocked, preventing the user from interacting with your page. It is one of the Web Vitals and is a replacement for the field-only First Input Delay (FID) metric.”

Discussion

What I personally value about Google’s page experience approach is the current focus on usability, and maybe Google’s influence will help to reduce not only involuntary layout shift but also dark patterns and intentionally bad UX that seems to prevail on many commercial websites these days.

Irritated by weak empirical evidence, Peter Hedenskog took a critical stance on Core Web Vitals, questioning Google’s monopoly on web performance metrics.

Maybe Google should use its current position not only to promote human-centered usability but rather add environmental metrics like a website’s carbon footprint the sooner the better.

Credits

This article is mostly based on other people’s work, mainly by Google’s Addy Osmani and Houssein Djirdeh, but I also owe to the German WordPress community, especially WordPress Düsseldorf meetup #52 earlier this year!

Originally publishing on dev.to, I have released the same (slightly updated) article here on medium to share my learnings with a larger audience.

Conclusion

Care about your users, optimize time to interactive, and prevent layout shift!

My personal prediction: also care about sustainability and reduce your website’s carbon footprint! Hopefully, this might become another important ranking factor in the future.

Originally published at https://dev.to on March 2, 2021.

--

--

Ingo Steinke

Sustainable Creative Web Developer in Germany. Helping to build a fast and friendly, accessible, ethical and ecological word wide web.