Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A deep dive into Google’s Core Web Vitals - Aff...

A deep dive into Google’s Core Web Vitals - AffiliateCon 2021

My talk from the 2021 AffiliateCon titled "A deep dive into Google’s Core Web Vitals" covering #webperf topics to make any website REALLY fast! Need help implementing? Reach out to us!

Bastian Grimm

November 07, 2022
Tweet

More Decks by Bastian Grimm

Other Decks in Technology

Transcript

  1. A deep dive into Google’s Core Web Vitals Because sometimes

    fast isn’t fast enough! Bastian Grimm, Peak Ace AG | @basgr
  2. For me, there is nothing worse than having to wait

    for anything to load! I'm really impatient
  3. pa.ag @peakaceag 5 USA Today created a super fast GDPR-compliant

    domain 500 vs 34 requests, 140 vs 0 JS files, 6 vs 1 CSS, 5.01 MB vs 356 KB in size, etc. EU US Start Render 0.300 sec 1.700 sec First Interactive 0.345 sec 3.604 sec Load Time 0.995 sec 19.261 sec Speed Index 443 8,792 Total Requests 34 859 Bytes in 356 KB 5,092 KB
  4. pa.ag @peakaceag 6 Let’s recap your users’ expectations: Slow page

    loading time is a major factor in page abandonment. According to a Nielsen report, 47% of people expect a website to load within two seconds, and 40% will leave a website if it does not load fully within three seconds.
  5. Fast loading time plays an important role in overall user

    experience! Performance is about user experience!
  6. pa.ag @peakaceag 8 Revisited: page speed already is a ranking

    factor Source: http://pa.ag/2iAmA4Y | http://pa.ag/2ERTPYY
  7. pa.ag @peakaceag 9 What most people tend to forget… Performance

    is a relative concept! Source: https://pa.ag/38jyW6a A site might be fast for one user (on a fast network with a powerful device) but slow for another user (on a slow network with a low-end device). Two sites may finish loading at the exact same time, yet one may seem to load faster (if it loads content progressively rather than waiting until the end). A site might appear to load quickly but then respond slowly (or not at all) to user interaction.
  8. pa.ag @peakaceag 10 Google’s 2020 Core Web Vitals set, at

    a glance The current set focuses on three aspects of user experience - loading, interactivity, and visual stability - and includes the following metrics (and their respective thresholds): Source: https://pa.ag/3irantb LCP measures loading performance. To provide a good UX, LCP should occur within 2.5 seconds. FID measures interactivity. To provide a good UX, pages should have an FID under 100 milliseconds. CLS measures visual stability. To provide a good UX, pages should maintain a CLS of less than 0.1. i
  9. pa.ag @peakaceag 12 Performance measurement scoring & metrics, at a

    glance But what do these numbers actually mean? And how are they different from what we have used before? Source: https://pa.ag/38jyW6a Historically, web performance has been measured with the load event. However, even though load is a well-defined moment […], that moment doesn't necessarily correspond with anything the user cares about.
  10. pa.ag @peakaceag 13 If you’re not familiar with Google Lighthouse…

    There are several ways to install Google Lighthouse and run it to audit your webpages: Google Chrome Google Chrome Extension Node Command Line Interface (CLI) ▪ Navigate to the webpage you wish to run the audit on. ▪ Right-click on the page and click “inspect element” or press CTRL + SHIFT + I (for dev. tools) ▪ Navigating to the audits tab, find the Lighthouse logo and CTA which says “Perform an audit…” ▪ Simply click on the audit button and it should show you 4 options to run; press “Run Audit”. ▪ Download the extension (https://pa.ag/3cAXxqg) and add it to your Google Chrome browser. ▪ Navigate to the webpage you want to audit. ▪ Hit the Lighthouse Chrome extension icon and let Lighthouse run. ▪ Download and install Google Chrome ▪ Install a current and stable version of Node (>=6) ▪ Run the following command line to install the global Lighthouse npm package: npm install -g lighthouse ▪ Run Lighthouse by typing the following into the CLI: lighthouse https://bastiangrimm.com/
  11. pa.ag @peakaceag 14 To start, visit any webpage you want

    to test in Chrome Press “CTRL+SHIFT+I“, find the “Lighthouse“ tab, adjust settings & click “Generate report“ #1 #2 #3 #4 Make sure to always run Lighthouse in Chrome Incognito mode! #5 #6
  12. pa.ag @peakaceag 15 Overall scores (range: 0 – 100) depending

    on which categories you selected Detailed performance measurement breakdown using the most common metrics, e.g. FCP/FMP Film strip view with various browser paint timings Import/export as well as various “pretty print” and JSON data formats
  13. pa.ag @peakaceag 18 Important: metrics are measured in one of

    two ways: To find yours: Chrome > dev tools > performance > timings In the lab: using tools to simulate a page load in a consistent, controlled environment In the field: on real users actually loading and interacting with the page”
  14. pa.ag @peakaceag 19 Track paint times using PerformanceObserver Or even

    better: use the official web vitals JS library Get the web-vitals JS library: https://pa.ag/2VlVKy6
  15. pa.ag @peakaceag 20 This is what it looks like in

    Google Analytics Behaviour > Events > Pages: performance metrics [first-contentful-paint] LCP , FID as well as CLS available in Google Analytics:
  16. Before we start optimising, here is a brief overview of

    which metrics are influenced by which components: What impacts what?
  17. pa.ag @peakaceag 23 Optimising for Core Web Vitals such as

    LCP, FID and CLS? An overview of the most common issues and respective fixes: LCP is primarily affected by: ▪ Slow server response time ▪ Render blocking JS/CSS ▪ Resource load times ▪ Client-side rendering FID is primarily affected by: ▪ Third-party code ▪ JS execution time ▪ Main thread work/business ▪ Request count & transfer size CLS is primarily affected by: ▪ Images without dimensions ▪ Ads, embeds and iframes without dimensions ▪ Web fonts (FOIT/FOUT) Optimizing for LCP: ▪ Server response times & routing ▪ CDNs, caching & compression ▪ Optimise critical rendering path ▪ Reduce blocking times (CSS, JS, fonts) ▪ Images (format, compression, etc.) ▪ Preloading & pre-rendering ▪ Instant loading based on PRPL Optimising for FID: ▪ Reduce JS execution (defer/async) ▪ Code-split large JS bundles ▪ Break up JS long tasks (>50ms) ▪ Minimise unused polyfills ▪ Use web workers to run JS on a non-critical background thread Optimising for CLS: ▪ Always include size attributes on images, video, iframes, etc. ▪ Reserve required spaces in advance ▪ Reduce dynamic injections
  18. The code and resources required to render the initial view

    of a web page Critical rendering path
  19. pa.ag @peakaceag 27 CSSOM: the CSS Object Model ▪ The

    CSSOM is a “map” of the CSS styles found on a web page. ▪ It’s much like the DOM (Document Object Model), but for CSS rather than HTML. ▪ The CSSOM combined with the DOM is used by browsers to display web pages. body font-size:18px; h1 font-size:22px; a font-size:12px; div font-size:16px; p font-size:12px; p font-size:16px;
  20. pa.ag @peakaceag 28 Web browsers use the CSSOM to render

    a page If this is external CSS, the browser needs to wait for the download.
  21. pa.ag @peakaceag 29 Google doesn’t make a single CSS GET

    request! Because requesting external CSS is more expensive than inlining everything.
  22. pa.ag @peakaceag 30 How to know which CSS is critically

    required “Critical” renders in multiple resolutions and builds a combined/compressed CRP CSS: Critical & criticalCSS on GitHub: http://pa.ag/2wJTZAu & http://pa.ag/2wT1ST9 ▪ Minimum: a snapshot of CSS rules to render a default desktop resolution (e.g. 1280x1024). ▪ Better: various snapshots for mobile phones, pad/s & desktop/s – manually, that’d be a lot of work!
  23. pa.ag @peakaceag 31 Putting it all together Fit the HTML,

    CSS & JS that are necessary for “Start Render” into the first 14kB round trip! <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>CRP loading demo</title> <!-- critical CSS goes here --> <style> h1 { colour: green; } </style> <!-- use async preload // no IE, Edge & some other unimportant ones (http://caniuse.com/#search=preload) -- > <link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'" /> <!--noscript for req. without JS --> <noscript><link rel="stylesheet" href="non-critical.css"></noscript> <!-- include polyfill for shitty browsers --> <script> *! loadCSS. [c]2017 Filament Group, Inc. MIT License */ (function(){ ... } ()); /*! loadCSS rel=preload polyfill. [c] 2017 Filament Group, Inc. MIT License */ (function(){ ... } ()); </script> </head> <body> </body> </html> <!-- use async preload // no IE, Edge & some other unimportant ones (http://caniuse.com/#search=preload) --> <link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'" /> <!-- critical CSS goes here --> <style> h1 { colour: green; } </style> <!-- use async preload // no IE, Edge & some other unimportant ones (http://caniuse.com/#search=preload) --> <link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'" /> <!--noscript for req. without JS --> <noscript><link rel="stylesheet" href="non-critical.css"></noscript> *! loadCSS. [c]2017 Filament Group, Inc. MIT License */ (function(){ ... } ()); /*! loadCSS rel=preload polyfill. [c] 2017 Filament Group, Inc. MIT License */ (function(){ ... } ()); Inline your critical CSS. 1 Loading non-critical CSS async using rel=“preload“. 2 Apply the CSS once it has finished loading via “onload“. 3 Fallback for non-JS requests. 4 Implement loadCSS script for older browsers. 5
  24. pa.ag @peakaceag 32 Almost brand new: content-visibility, a new CSS

    property content-visibility enables the user agent to skip an element's rendering work, including layout & painting, until it is needed – and therefore makes the initial load much faster! Source: http://pa.ag/2Wxn399
  25. Higher quality, (more) efficient data compression, smaller files as well

    as loading strategies for faster image delivery Image optimisation
  26. pa.ag @peakaceag 34 What are you looking for in your

    Lighthouse report? Opportunities > Properly size images
  27. pa.ag @peakaceag 35 60% of all web traffic is made

    up of images... The average website transfers between 900 and 970KB of images per URL! Source: https://pa.ag/2xwHOFN
  28. pa.ag @peakaceag 36 Basic optimisation for all images: put ‘em

    on a diet! tinyPNG & tinyJPG for smart (lossy) compression & removal of metadata et al. API access, various plug-ins (WP , etc.) as well as direct integration into Photoshop. Source: http://tinypng.com | http://tinyjpg.com
  29. pa.ag @peakaceag 38 WebP: Google’s alternative to JPEG, PNG, and

    GIF Lossy & lossless compression, transparency, metadata, colour profiles, animation, and much smaller files (30% vs. JPEG, 80% vs. PNG) – but only in Chrome, Opera & Android. Everything about WebP: http://pa.ag/1EpFWeN / & WebP support: http://pa.ag/2FZK4XS
  30. pa.ag @peakaceag 39 You can use WebP with an on-the-fly

    replacement Swap PNG and JPEG images per re-write (i.e. using nginx/Apache configuration). Alternatively: the <picture> element allows you to manually specify multiple file types. VS.
  31. pa.ag @peakaceag 40 bestbuy.com could save >50% in image size/traffic

    Better compression combined with modern, responsive images & formats
  32. pa.ag @peakaceag 41 Say hello to AVIF – supported in

    Chrome 85 & Firefox 80 Developed by the Alliance for Open Media in collaboration with Google, Cisco, and Xiph.org to be an open-sourced and royalty-free image format: Source: https://pa.ag/3gK9Gdk AV1 (.avif) is basically a super-compressed image type. Netflix has already considered .avif superior to the JPEG, PNG, and even the newer WebP image formats for its image quality to compressed file size ratio. i
  33. pa.ag @peakaceag 42 Also, ensure to generate responsive images! One

    image for all screen resolutions and devices is not enough. An image per pixel is too much; responsivebreakpoints.com can help! More: https://pa.ag/2NNBvVm & https://pa.ag/2C6t6aQ
  34. pa.ag @peakaceag 43 What are you looking for in your

    Lighthouse report? Opportunities > Defer offscreen images
  35. pa.ag @peakaceag 44 Off-load your images using the “lazySizes” loader

    The high-performance lazy loader for images, iFrames and more, detects any visibility changes (e.g. through user interaction, CSS or JS) without configuration. More on GitHub: https://pa.ag/2VOywil Especially important for mobile since you only want to load images that are actually visible! You can even lazy load responsive images (with automatic sizes calculation)
  36. pa.ag @peakaceag 45 Things are getting much easier now: loading

    = lazy Performance benefits paired with SEO friendliness (and no JS) simultaneously Tip: This now also works for <iframe src=“…“ loading=“lazy“> :
  37. Remember: to prevent any CLS, it‘s of utmost importance to

    specify width and height attributes, e.g. for images, iframes, videos, etc. Always specify dimensions!
  38. pa.ag @peakaceag 48 What are you looking for in your

    Lighthouse report? Diagnostics > Ensure text remains visible during webfont load
  39. pa.ag @peakaceag 49 >70% of all websites use at least

    one non-standard font Result: 111KB of additional data and on average, 4-5 additional HTTP requests Source: https://pa.ag/2I7vAHC
  40. pa.ag @peakaceag 50 The traditional method: using external CSS Easy

    to use, but with one big disadvantage: it’s render-blocking! CSS’s (font) call to Google causes the render to stop/block until the download has finished!
  41. FOIT (flash of invisible text) or FOUT (flash of unstyled

    text) can cause irritating flickering Asynchronous?
  42. pa.ag @peakaceag 52 Fighting the flash of unstyled text/content Make

    your fall-back font match the intended web font (letter spacing, heights, etc.), otherwise this will cause layout shifts: Give it a try: https://pa.ag/2qgE8EH
  43. pa.ag @peakaceag 53 Fighting the flash of invisible text/content Stuff

    to play around with: various “font-display” strategies for CSS More: http://pa.ag/2eUwVob ‘font-display’ enables the text to be displayed while the font itself is still loading.”
  44. pa.ag @peakaceag 54 Non-blocking CSS loading means massive gains Optional

    results in a 100ms blocking period, but no swap - even after it’s downloaded (only on “next page” view). This feels much faster! Go to your CSS file, look for @font-face and add ’font-display:optional’ – there hasn’t been a safer & easier gain in #webperf in a long time! Invisible Fallback Webfont 3s 0s 100ms 3s 100ms Block Swap Fallback Optional
  45. pa.ag @peakaceag 55 Btw: if you‘re using Google Fonts, you’ll

    love this one: Adding “display=swap“ to the URL will achieve the same result! However, I’d rather not rely on (external) web fonts at all. Source: https://pa.ag/2BbLK03 https://fonts.googleapis.com/css?family=Lato https://fonts.googleapis.com/css?family=Lato&display=swap
  46. pa.ag @peakaceag 57 What are you looking for in your

    Lighthouse report? Opportunities > Reduce server response times (TTFB)
  47. pa.ag @peakaceag 58 Should I worry about my TTFB at

    all? Spoiler: YES! And what‘s an acceptable result to aim for? More: http://pa.ag/2lKCIRH & http://pa.ag/2mkJTMY Many possible causes of slow server responses, and therefore many possible ways to improve: ▪ Optimise the server's application logic to prepare pages faster. ▪ Optimise how your server queries databases (or migrate to faster database systems). ▪ Upgrade your server hardware to have more memory or CPU.
  48. pa.ag @peakaceag 59 What are you looking for in your

    Lighthouse report? Opportunities > Reduce the impact of third-party code
  49. pa.ag @peakaceag 60 Especially for global businesses, CDNs can be

    a great help Use CDNPerf.com to find the one that suits you best, depending on where you are and which regions/countries you‘re predominantly serving. This will positively impact TTFB! Give it a try: https://www.cdnperf.com/ VS
  50. pa.ag @peakaceag 61 CDN recommendation? Check out Cloudflare! Cloudflare Workers

    and their approach to serverless JavaScript is super powerful:
  51. pa.ag @peakaceag 62 What are you looking for in your

    Lighthouse report? Opportunities > Preload key requests
  52. pa.ag @peakaceag 63 Breakdown of requests for Netdoktor.de (waterfall view)

    When you‘re using a CDN, or getting resources from other, external (sub-) domains, make sure to pre-* respectively: DNS lookup for the asset server (static.netdoktor.de) takes ~300 ms
  53. pa.ag @peakaceag 64 DNS pre-fetching in <head>: 81ms = 75%

    time saved Very useful for other hosts' resources that you want to use at a later stage.
  54. pa.ag @peakaceag 65 Taking it one step further: pre-connecting HTTPS

    Don't just pre-resolve DNS names – also allow for TLS-handshake.
  55. pa.ag @peakaceag 66 Or: rel=preload late-discovered hero images faster You

    can use <link rel=preload> to optimize Core Web Vitals; specifically, how soon the primary imagery visible in the viewport loads, which positively impacts LCP: Source: https://pa.ag/31DGPmz <link rel="preload" as="image" href="your-hero-image.jpg"> Preload can substantially improve LCP, especially if you need critical images (like hero images) to be prioritized over the loading of other images on a page. While browsers will try their best to prioritize the loading of images in the visible viewport, <link rel=preload> can offer a significant boost in priority.
  56. pa.ag @peakaceag 67 This has also just recently landed in

    Lighthouse: To optimise Largest Contentful Paint, you should preload your critical images. Lighthouse 6.5 has suggested how and where to do this Source: https://pa.ag/3mBkqOi
  57. Create awareness (and limitations) beyond just one team; and make

    them all commit to hard numbers! Performance budgets
  58. pa.ag @peakaceag 69 Google introduced performance budgets in Lighthouse LightWallet

    for budgeting: (e.g. page weight, request and timing-based budgets) Source: http://pa.ag/2WxNjQK "budgets": [ { "cpuThrottling": 1, "connectionType": "wifi", "pageWeight": [ { "resourceType": "script", "budget": 300 }, { "resourceType": "stylesheet", "budget": 50 } ], "timings": [ { "metric": "timeToInteractive", "budget": 5000, "tolerance": 1000 }, { "metric": "firstMeaningfulPaint", "budget": 2000, "tolerance": 500 } ] } ]
  59. pa.ag @peakaceag 70 Don‘t know where to start? Use the

    performance budget calculator to synchronise your spending with your goals: More: http://bit.ly/perf-budget-calculator
  60. pa.ag @peakaceag 73 The labels “Poor”, “Needs improvement”, and “Good”

    are applied to a URL on specific device type. If a URL is below the threshold of data for a given metric, that metric is omitted from the report. In case you didn’t notice: things are much better in GSC! Search Console now contains a “Core Web Vitals“ report for desktop and mobile. This is current, real-world data based on the Chrome UX report: More: https://pa.ag/3eKHpEe i
  61. pa.ag @peakaceag 74 Chrome Web Vitals extension Preview: comparing local

    metrics to field data from CrUX Get the extension: http://pa.ag/3mG1OMW | Preview: https://pa.ag/2KmQrfQ
  62. pa.ag @peakaceag 75 Another Chrome extension: Core SERP Vitals Show

    real world Core Web Vitals data from the CrUX report in Google search results: Source: http://pa.ag/34w4fvv
  63. pa.ag @peakaceag 76 Run multiple Lighthouse reports at once, for

    free! Visit batchspeed.com and throw in the URLs you want to measure with Lighthouse More: batchspeed.com
  64. pa.ag @peakaceag 78 Lighthouse Parade: let‘s scale things up! A

    Node.js command line tool that crawls a domain and compiles a report with Lighthouse performance data for every page: Give it a try: http://pa.ag/2WAAiWu With a single command, the tool will crawl an entire site, run a Lighthouse report for each page, and then output a spreadsheet with the aggregated data. […] Each row in the spreadsheet is a page on the site, and each individual performance metric is a column. This makes it very easy to perform high-level analysis because you can sort the rows by whichever metric you are analysing.
  65. pa.ag @peakaceag 79 CrUX report comparison at a glance Easy

    comparison of desktop vs phone results – or yourself vs competition, etc. More: https://crux-compare.netlify.app/ | Source: http://pa.ag/3nE02NB Q: Is there a difference between desktop and mobile ranking? A: At this time, using page experience as a signal for ranking will apply only to mobile search.
  66. pa.ag @peakaceag 80 Very handy: Layout Shift GIF Generator Easily

    identify problematic layout shifts in the viewport on mobile and desktop. Available as a simple command line tool, or as an online tool. Source: https://pa.ag/3iIJdOU
  67. pa.ag @peakaceag 81 SpeedCurve: all you need in #webperf monitoring

    By far the most comprehensive toolset on the market: More: https://speedcurve.com/