Optimising Core Web Vitals for SPAs

Simon Hearne

Web Performance Consultant

Hi Simon! I was wondering if you could help with...

Don't panic!

Core Web Vitals are your friend, not your foe

In this talk:

  • What the Core Web Vitals are
  • Why they matter (to you and Google)
  • Why SPAs are special
  • How to improve and monitor progress

Core Web Vitals?

Core Web Vitals?

Not just that Google thing

CWVs are proxies of
User Experience

Largest Contentful Paint
How fast it feels
Cumulative Layout Shift
How jumpy it is
First Input Delay
How interactive it feels

Field vs. Lab

πŸ§ͺ Lab

Controlled tests of a single page / interaction

🌍 Field

Real data from real users on the web

Distributions & Percentiles

  • CWV measured in the field, where data is noisy
  • We use summary metrics to make sense of the noise
  • 75th percentile - ΒΌ experiences are worse, ΒΎ better

Results will differ between tools

  • Google Analytics + web-vitals.js 🌍
  • Pagespeed Insights 🌍πŸ§ͺ
  • Search Console 🌍
  • Real User Monitoring 🌍
  • WebPageTest πŸ§ͺ

Who uses what?

  • Search Console for SEO folks
  • CrUX & RUM for product
  • PSI & WebPageTest for engineers

Google only cares about field metrics 🌍!

Why Core Web Vitals Matter

Google Logo

Search ❀️ CWV ❀️ Speed

SEO impact of Core Web Vitals

SEO is a πŸ₯• to create better UX

Don't expect massive ranking boosts

CWV are not pass / fail!

If max ranking boost == 1, this page will get ~0.7

SEO impact of Core Web Vitals

A brief history of #WebPerf

  • 2010 - Navigation Timing API
  • 2017 - Paint Timing API
  • 2019 - ALL THE APIS (in Chrome)
    • LargestContentfulPaint API
    • LayoutInstability API
    • EventTiming API

Web vitals are the best performance metrics we've ever had

And they're collected from users around the world for free!


SPAs break a lot of stuff

SPAs break performance APIs

SPAs break performance APIs

One load event per session, one FCP, one LCP...

LCP is only measured on the
first page load

CLS is measured throughout
the whole session

CLS is measured throughout
the whole session

This breaks page-level attribution 😱

FID is only measured on the
first page load

In summary...

SPA websites are penalised by
ignoring mid-session navigations

except CLS - where the worst 1-5s window is captured

Optimising CWVs on SPAs

Largest Contentful Paint

Let's remove preloads


HTML Size Analyser

Where we got to (3G)

LCP top tips

  • SSR all landing pages
  • Defer / reduce / remove expensive JS
  • Increase hero element priority
  • Only preload critical assets
  • No cross-origin requests in critical path
  • Reduce HTML size (<50kB compressed)

Image LCP?

  • Ensure <img src=""> in HTML source
  • Ensure loading attribute is not "lazy"
  • Try fetchpriority="high" attribute
  • Keep hero images <100kB
  • Use modern formats
    (AVIF > WEBP > JPEG > PNG > GIF)

Consent LCP?


Consent LCP?

  • Work with CMP to improve render time
  • Break text into separate paragraphs!

Cumulative Layout Shift

CLS can come from anywhere!

  • On page load (easy)
  • On scroll (medium)
  • On (slow) interactions (tricky)

Remember that CLS attribution is broken in Search Console

CLS top tips

  • Ensure all images have size attributes
    (or aspect-ratio)
  • Preload critical web fonts
  • Use transforms instead of top etc.
  • Pre-allocate space for dynamic elements
  • Record profiles of key interactions

First Input Delay

Your FID should be green!

Web Almanac 2021

FID top tips

  • Focus on Total Blocking Time
  • Break tasks into small chunks
  • Consider PartyTown?

Interaction to Next Paint (INP)

INP may replace FID


INP top tips

  • Provide visual feedback to user input
  • Don't attach blocking JS on input events

In summary

  • CWVs are great performance metrics
  • CrUX data is free RUM!
  • SEO impact is low
  • Optimising CWV improves UX

Links & Tools

Thank you πŸ™