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

Picture Perfect - An Image Optimization Talk

Picture Perfect - An Image Optimization Talk

Learn the tips and tricks that help production sites deliver images that have optimal Largest Contentful Paint and minimum Cumulative Layout Shift.

96270e4c3e5e9806cf7245475c00b275?s=128

Addy Osmani

June 02, 2022
Tweet

More Decks by Addy Osmani

Other Decks in Technology

Transcript

  1. Addy Osmani Picture Perfect Toronto WebPerf https://unsplash.com/photos/uf-IaeduFfk

  2. None
  3. Optimizing images. How hard could it be?

  4. None
  5. Image optimization is an evolving topic.

  6. Major changes in the image landscape • WebP support in

    all modern browsers • AVIF image decode support landing in Chrome & Firefox • JPEGXL decoding behind a fl ag in Chrome • Lazy-loading images in Chrome, FF, Safari TP. A default in WordPress • Compute img/video aspect ratio from width/height attributes • FF support for preload, Chrome: imagesrcset and imagesizes on link rel=preload • width/height on <source> elements for <picture> • and more! 2020-2021
  7. The modern <img> element <img src="donut-800w.jpg" alt="A delicious donut" width="400"

    height="400" srcset="donut-400w.jpg 400w, donut-800w.jpg 800w" sizes="(max-width: 640px) 400px, 800px" loading="lazy" decoding="async" style="background-size: cover; background-image: url(data:image/svg+xml;base64,[svg text]);"> Lazy-load Async decode SET DIMENSIONS TO AVOID LAYOUT SHIFTS Placeholder
  8. 50% of the brain is involved in visual processing Time

    to get the sense of a visual scene 0.01s How much we recall of what we see or do vs. 20% of what we read. 80% Increase in willingness to read due to color visuals. 80% Neuroscience How much audiences more likely to be persuaded by a talk with visuals vs. a purely verbal one 17% To process a symbol and 100ms to attach meaning to it. 150ms Sources: goo.gle/imgsci
  9. None
  10. There are many ways to load an image. https://goo.gle/3eLzPux

  11. Images impact Web Vitals in a number of ways

  12. Optimal image serving for Web Vitals • For a fast

    Largest Contentful Paint • Request your key hero image early • Use <picture>, srcset + e ff i cient modern image formats • Avoid wasting pixels (compress, don't serve overly high DPR images) • Lazy-load o ff screen images (reduce network contention for key resources) • For a low Cumulative Layout Shift • Set dimensions (width, height) on your images • Use CSS aspect-ratio or aspect-ratio boxes to reserve space otherwise • For a low impact First Input Delay • Avoid images causing network contention with other critical resources like CSS and JS.
  13. Largest Contentful Paint Element Lighthouse Audit function getLCPDebugTarget(entries) { const

    lastEntry = entries[entries.length - 1]; return lastEntry.element; } LCP API (RUM) web.dev/debug-web-vitals-in-the- fi eld/ User devices have di ff erent screen resolutions, which results in di ff erent page layouts and thus di ff erent elements being visible within the viewport. Content may be personalized for the current user, so the LCP candidate element could vary wildly from user to user. 🔬 ⛰
  14. Images & Developer tooling Identify images that could be served

    in a more modern format
  15. Serving Modern Image Formats <picture> <source srcset="puppy.jxl" type="image/jxl"> <source srcset="puppy.avif"

    type="image/avif"> <source srcset="puppy.webp" type="image/webp"> <source srcset="puppy.jpg" type="image/jpeg"> <img src="puppy.jpg" alt="Cute puppy"> </picture>
  16. Picking an image format Compression • Compression • Speed •

    Limitations • Animation • Features • Tooling
  17. JPEG 80 vs AVIF 70 vs WEBP 85 54% size

    reduction vs JPEG 26% size reduction vs JPEG https://www.industrialempathy.com/posts/avif-webp-quality-settings/
  18. When lossy compression is good enough, both AVIF and JPEG

    XL deliver significantly better results than the existing web codecs, including WebP.
  19. Original 1.7MB How much can we get out of ~70KB?

  20. JPEG 68.3KB

  21. JPEG 68.3KB

  22. WEBP 67.7KB

  23. HEIC 69.7KB

  24. AVIF 67.6KB

  25. JXL 67.0KB

  26. Picking an image format Speed & Features

  27. Image Optimization Tooling Squoosh • Imagemin • ImageMagick • Sharp

    / Jimp • Thumbor • ImageOptim • XnConvert • Image CDNs
  28. Images & Developer tooling Image format debugging

  29. Identify images that can be better sized Properly size images

  30. Images without dimensions

  31. Layout Shifts from images without dimensions Lighthouse audit function getCLSDebugTarget(entries)

    { const largestShift = entries.reduce(( return a && a.value > b.value ? a : }); if (largestShift && largestShift.sour const largestSource = largestShift. return a.node && a.previousRect.w b.previousRect.width * b.prev }); if (largestSource) { return largestSource.node; } } PerformanceObserver
  32. Lots of factors determine the best image size • Many

    factors determine the best image size • Screen size and resolution • Viewport • Layout and responsive breakpoints • Device pixel ratio (physical resolution) • Art direction Can one size fi t all?
  33. Responsive Images: srcset and sizes <img src="donut-800w.jpg" alt="A delicious pink

    donut." width="400" height="400" srcset="donut-400w.jpg 400w, donut-800w.jpg 800w" sizes="(max-width: 640px) 400px, 800px">
  34. <img srcset> by width and density Responsive images

  35. Device Pixel Ratio (DPR) / Pixel Density Capping Responsive images

  36. Image Aspect Ratio Reserve space for responsive and lazy-loaded images

    Padding-top hack Mapped aspect-ratio Explicit aspect-ratio
  37. Enhanced image preview in DevTools File size, rendered size, rendered

    aspect ratio, intrinsic size, intrinsic aspect ratio
  38. Image lazy-loading Defer o ff screen images

  39. Image lazy-loading Eager image fetching

  40. Lazy-loading responsive images <!-- Lazy-load images in <picture>. <img> is

    the one driving image loading --> <picture> <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" loading="lazy"> </picture> <img src="donut.jpg" alt="A delicious pink donut." loading="lazy" width="400" height="400"> Lazy-loading images
  41. Image lazy-loading Lazy image fetching

  42. Image discovered late - loaded via JS LCP image preloaded

  43. Preload Largest Contentful Paint image Lighthouse audit

  44. Request your image early <link rel="preload" as="image" href="donut.jpg"> <link rel="preload"

    as="image" href="donut.webp" type="image/webp"> <link rel="preload" as="image" href="donut.jpg" imagesrcset=" poster_400px.jpg 400w, poster_800px.jpg 800w, poster_1600px.jpg 1600w" imagesizes="50vw">
  45. Blurry placeholder images Approximate the fi nal image before it

    loads in
  46. Placeholder using background-image <img src="donut-800w.jpg" alt="A delicious donut" width="400" height="400"

    srcset="donut-400w.jpg 400w, donut-800w.jpg 800w" sizes="(max-width: 640px) 400px, 800px" loading="lazy" decoding="async" style="background-size: cover; background-image: url(data:image/svg+xml;base64,[svg text]);"> Placeholder Final image
  47. https://unsplash.com/photos/qDY9ahp0Mto

  48. Next.js Image Component • Automatic srcsets for images • Enforced

    sizing to prevent layout shift • Automatic lazy-loading of o ff screen assets • Framework-speci fi c asset prioritization optimizations • Flexible layout options • Customizable loader support for any image server or CDN Features and bene fi ts Up to 60% faster LCP and up to 100% reduced CLS
  49. Next.js Image Component Features and bene fi ts • Automatic

    srcsets for images • Enforced sizing to prevent layout shift • Automatic lazy-loading of o ff screen assets • Framework-speci fi c asset prioritization optimizations • Flexible layout options • Customizable loader support for any image server or CDN Up to 60% faster LCP and up to 100% reduced CLS
  50. Images in Next.js without Next Image import Head from 'next/head';

    export default function Index() { return ( <div> <Head><title>Create Next App</title></Head> <main> <div> <img src="/donut1.jpeg" alt="Donut" height={700} width={700} /> <img src="/donut2.jpeg" alt="Donut" height={700} width={700} /> </div> </main>
  51. Next.js Image Component

  52. Images in Next.js with Next Image import Head from 'next/head';

    import Image from 'next/image'; export default function Index() { return ( <div> <Head><title>Next.js Image Component</title></Head> <main> <div> <Image src="/donut1.jpeg" alt="Donut" height={700} width={700} /> <Image src="/donut2.jpeg" alt="Donut" height={700} width={700} /> </div>
  53. Next.js Image Component

  54. Next.js Image Component

  55. 31% improvement in LCP increased sales by 8% Optimizations to

    improve LCP included resizing their hero image, optimizing SVGs and using media queries to limit loading o ff screen images. Their optimizations to LCP included a 2.5s saving from switching their fi rst large image from being behind JavaScript (client-side hydration) to being directly in the main HTML document. 70% improvement in LCP correlated with a 76% reduction in load abandonment They determined shifts were caused after their hero images were loaded and snapped in for the fi rst view. They used Aspect Ratio Boxes to reserve space before their image was loaded. Optimizations to CLS helped increase News page views per session by 15% French Fashion house Chloè used Link Preload to preload their 1x and 2x Hero images, which were previously bottlenecked by a render-blocking script. Preloading 1x and 2x Hero images bottlenecked by render- blocking script improved LCP by 500ms (based on CrUX)
  56. Thank you! @addyosmani

  57. Archive Slides that won't make the cut this time. •

    We can still summarize or include as notes.
  58. None
  59. Automating Image Optimization in frameworks Image Components • Modern image

    components that build on <img>, like Next.js <Image> (for React) and Nuxt image (for Vue) try to bake in as many of these concepts as possible by default. • You can of course also do this manually just using the <img> element directly. • If using 11ty for your static sites, try the 11ty high-performance blog template.
  60. Avoid the download and shrink pattern Better to use srcset,

    sizes, <picture> to serve images w/right dimensions
  61. Compression

  62. Speed

  63. Limitations

  64. Features

  65. Codec Comparison https://www.industrialempathy.com/posts/avif-webp-quality-settings/#visual-veri fi cation

  66. JPEG@80 213KB

  67. WEBP@90 206KB Size reduction 4% vs JPEG DSSIM 0.00103

  68. AVIF@75 88KB Size reduction 59% vs JPEG DSSIM 0.00140

  69. JXL@61 80KB Size reduction % vs JPEG DSSIM

  70. JPEG 80 vs WebP 85 (26% size reduction vs JPEG)

  71. JPEG 80 vs AVIF 70 (54% size reduction vs JPEG)

  72. Low Fidelity Comparison https://cloudinary.com/blog/time_for_next_gen_codecs_to_dethrone_jpeg

  73. LCP image in the loading filmstrip WebPageTest

  74. CLS

  75. Images & Developer tooling Largest Contentful Paint element

  76. Images & Developer tooling Image Intrinsic Size

  77. <img srcset> by width and density Responsive images

  78. Device Pixel Ratio (DPR) / Pixel Density Capping Responsive images

  79. Device Pixel Ratio (DPR) / Pixel Density Capping Responsive images

  80. Responsive Breakpoints from Cloudinary Responsive images

  81. Serving modern image formats Compression

  82. Images & Developer tooling Cloudinary's image analyst tooling

  83. Animation

  84. Basic <img> element <img src="donut.jpg" alt="A delicious pink donut." width="400"

    height="400">
  85. Lazy-loading images <img src="donut.jpg" alt="A delicious pink donut." loading="lazy" width="400"

    height="400">
  86. Lazy-loading responsive images <!-- Lazy-load images in <picture>. <img> is

    the one driving image loading so <picture> and srcset fall off of that --> <picture> <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x"> <source srcset="small.jpg 1x, small-hd.jpg 2x"> <img src="fallback.jpg" loading="lazy"> </picture>
  87. Request your image early <link rel="preload" as="image" href="donut.jpg"> <link rel="preload"

    as="image" href="donut.webp" type="image/webp"> <link rel="preload" as="image" href="donut.jpg" imagesrcset=" poster_400px.jpg 400w, poster_800px.jpg 800w, poster_1600px.jpg 1600w" imagesizes="50vw">
  88. Request your image early <link rel="preload" as="image" href="donut.jpg" imagesrcset=" poster_400px.jpg

    400w, poster_800px.jpg 800w, poster_1600px.jpg 1600w" imagesizes="50vw">
  89. Image decoding <img src="donut-800w.jpg" alt="A delicious donut" width="400" height="400" srcset="donut-400w.jpg

    400w, donut-800w.jpg 800w" sizes="(max-width: 640px) 400px, 800px" loading="lazy" decoding="async">
  90. Responsive Breakpoint Generator

  91. Optimal image serving for Web Vitals • For a fast

    Largest Contentful Paint • Request your key hero image early • Use srcset + e ffi cient modern image formats • Avoid wasting pixels (compress, don't serve overly high DPR images) • Lazy-load o ff screen images (reduce network contention for key resources) • For a low Cumulative Layout Shift • Set dimensions (width, height) on your images • Use CSS aspect-ratio or aspect-ratio boxes to reserve space otherwise • For a low impact First Input Delay • Avoid images causing network contention with other critical resources like CSS and JS.