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

Adaptive Loading - Improving the UX for billions on low-end devices

96270e4c3e5e9806cf7245475c00b275?s=47 Addy Osmani
November 20, 2019

Adaptive Loading - Improving the UX for billions on low-end devices

Adaptive Loading is a web performance pattern where sites not just respond based on screen size - they adapt based on actual device hardware.

Any user can have a slow experience. In a world with widely varying device capabilities, a "one-size" fits all experience may not always work. Sites that delight users on high-end devices can be unusable on low-end ones, particularly on median mobile and desktop hardware and in emerging markets. What if we could adapt how we deliver pages to better cater for our user's constraints?

https://addyosmani.com/blog/adaptive-loading/
https://web.dev/adaptive-loading-cds-2019/
Video: https://youtu.be/puUPpVrIRkc

96270e4c3e5e9806cf7245475c00b275?s=128

Addy Osmani

November 20, 2019
Tweet

More Decks by Addy Osmani

Other Decks in Technology

Transcript

  1. Addy Osmani Chrome @addyosmani Adaptive Loading Improving the UX for

    billions on low-end devices Nate Schloss Facebook @n8schloss
  2. Any user can have a slow experience.

  3. None
  4. None
  5. Respect the user’s and

  6. Smartphone hardware varies CPU Memory Storage Screen Battery

  7. The Performance Gap On Mobile src: IHS Markit Smartphone Model

    Market Tracker 2019H + Geekbench V4
  8. If you want to build a fast site, use slow

    hardware
  9. The Performance Gap On Desktop src: Amazon (bit.ly/bestsellinglaptops - November,

    2019) + Geekbench V5, @addyosmani Highest selling laptops on Amazon (2019) CPU performance using Geekbench 5
  10. Do we need to deliver the exact same experience to

    every user?
  11. Adaptive Loading

  12. Demo

  13. Demo Open demo

  14. Fine-tune Data Transfer Use less bandwidth on slow connections Respect

    Data Saver preferences Reduce memory use on low-cost devices Optimize loading of memory-intensive resources Toggle memory-intensive animations Limit costly JavaScript on low-end devices Avoid loading CPU-heavy components Reduce CPU-intensive code execution Network Memory CPU
  15. Adaptive Loading React Hooks bit.ly/react-adaptive Experimental

  16. Adaptive Loading bit.ly/adaptive-angular Community bit.ly/adaptive-vue

  17. Home Products Product Item Component media Fast Adaptive Media Loading

    Slow Median Connection:
  18. const network = navigator.connection.effectiveType; console.log ("Effective connection type is "

    + network); // 3g Network-aware Resource Loading import { useNetworkStatus } from './network'; const { effectiveConnectionType } = useNetworkStatus(); ... switch(effectiveConnectionType) { case '3g': media = <img src='low-res-image.jpg'/>; break; case '4g': media = <video muted controls><source src='video.mp4'></video>; break;
  19. Demo Open demo

  20. const saveData = navigator.connection.saveData; if (saveData) { // Don’t load

    heavy resources } Data-Saver aware Resource Loading import { useSaveData } from './save-data'; const { saveData } = useSaveData(); ... return ( <div> { saveData ? <img src='...' /> : <video> } </div>
  21. Data Saver Mode For Images Reduction for data-usage from images

    on web. 96% incl disabled video autoplay 80% Twitter’s Data Saver mode presents images as a preview. The web renders a 64x64 blurred image (LQIP style). Users can tap to load large images. Previews load quick on 2G & 3G. Reduction for data-usage from images on iOS + Android 50%
  22. Demo Open demo WPT

  23. .image { background-image: url("original.webp"); } @media (prefers-reduced-data: reduce) { /*

    Save-Data: On */ .image { background-image: url("compressed.webp"); } } `prefers-reduced-data` bit.ly/csswg-prd Proposal
  24. const memory = navigator.deviceMemory console.log ("Device has at least "

    + memory + "GB of RAM.") // Device has at least 4GB of RAM Memory-aware Resource Loading import { useMemoryStatus } from './memory'; const { deviceMemory } = useMemoryStatus(); ... return ( <div> { deviceMemory < 4 ? <img src='...' /> : <video> } </div>
  25. Demo Open demo

  26. Page Request Check Device Class & Network Module Server responds

    zoom.js related.js cart.js “Lite” core experience for everyone High-end only features Adaptive Module Serving - The Future? vendor.js magnifier.js modal.js ui_library.js utilities.js /product-page product.js videos.js AR.js
  27. Home Products Product Item Component Image Viewer Zoom Carousel Image

    Viewer Low-end device High-end device Adaptive Code-splitting & Code-loading Core experience
  28. import React, { Suspense } from 'react'; const Sample =

    React.lazy(() => import('./Sample')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <Sample /> </Suspense> </div> ); } React.lazy() and Suspense
  29. Network-aware Code-splitting import React, { Suspense } from 'react'; const

    myComponent = React.lazy(() => { return new Promise(resolve => { navigator.connection ? resolve(navigator.connection.effectiveType) : resolve(null) }).then((effectiveType) => { switch (effectiveType) { case "3g": return import(/* webpackChunkName: "light" */ "./Light.js"); break; case "4g": return import(/* webpackChunkName: "heavy" */ "./Full.js"); break;
  30. Adaptive Serving Fast? Lazy-load more features, like zooming. Slow? Just

    load the core experience eBay are experimenting with adaptive serving using effectiveType. On a fast connection, features like product zooming will load on demand. On slow connections, they won’t.
  31. Demo Open demo

  32. const cores = window.navigator.hardwareConcurrency console.log ("# logical processor cores are

    " + cores) // 4 CPU Core-aware Resource Loading import { useHardwareConcurrency } from './hardware-concurrency'; const { numberOfLogicalProcessors } = useHardwareConcurrency(); return ( <div> { numberOfLogicalProcessors <= 4 ? <img src='...' /> : <video><source src='...'> } </div>
  33. Home Products Product Fast connection Slow connection Adaptive Data-fetching &

    Pre-fetching GraphQL server Database Database Database 5 results 25 results
  34. Disable video autoplay on slow networks Only prefetch in-viewport links

    on 4G if (!isOKConnection() || isDataSavingMode()) { // don't prefetch visible routes return; } Limit carousel image loads on Data Saver / 3G
  35. High-end Low-end Adaptive Capability Toggling Static Low frame-rate animation Full-fidelity

    animation High frame-rate
  36. Client Server Request client sends current Client Hints Adaptive Delivery

    with Client Hints Subsequent requests Accept-CH: Device-Memory,Save-Data,Viewport-Width Device-Memory: 4 Viewport-Width: 320 Save-Data: 1 <meta http-equiv="Accept-CH" content="Device-Memory, Viewport-Width, Save-Data"> Enable Added Response
  37. Demo Open demo

  38. User Agent String “Moto G4” “Single-core score: 684” Device Class

    Detection Device Name Detection Service RAM Device Class “Low-end” Geekbench CPU benchmarks Cores CPU score
  39. None
  40. Do not just respond based on screen size, adapt based

    on actual device hardware
  41. Web device classification at Facebook

  42. Web device classification at Facebook Define buckets

  43. Web device classification at Facebook Define buckets Integrate buckets into

    logging
  44. Web device classification at Facebook Define buckets Integrate buckets into

    logging Adapt loading based on buckets
  45. On mobile we get the device name in the UA,

    so we can use the year class concept. Grouping Hardware On Mobile
  46. “Mozilla/5.0 (Linux; Android 10; SM-G955U) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0

    Chrome/79.0.0.0 Mobile Safari/537.36” “Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.0.0 Mobile Safari/537.36” Mobile UserAgents tell us what the device is
  47. “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like

    Gecko) Chrome/79.0.0.0 Safari/537.36” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.0.0 Safari/537.36” On desktop things aren’t so obvious...
  48. • UA tells us OS, but not much else •

    What do we have? ◦ Most desktop browsers have: navigator.hardwareConcurrency ◦ Many desktop browsers have: navigator.deviceMemory Grouping Hardware on Desktop
  49. Creating desktop hardware buckets

  50. 1) Log hardwareConcurrency and deviceMemory

  51. 1) Log hardwareConcurrency and deviceMemory 2) Group by hardwareConcurrency, deviceMemory

    and OS when looking at perf data
  52. 1) Log hardwareConcurrency and deviceMemory 2) Group by hardwareConcurrency, deviceMemory

    and OS when looking at perf data
  53. 1) Log hardwareConcurrency and deviceMemory 2) Group by hardwareConcurrency, deviceMemory

    and OS when looking at perf data 3) Figure out buckets based on groupings
  54. When integrated into performance logging, hardware class reveals a more

    complete picture
  55. None
  56. Adaptivity should be considered in your core frameworks

  57. Think about animations Low End High End

  58. Mobile Websites

  59. Load fast vs respond fast

  60. if (isLowEndDevice()) { scheduler.unstable_forceFrameRate(15); }

  61. isInputPending

  62. Using consistent definitions for buckets in logging and adapting lets

    you easily see the full picture
  63. Adaptive Loading Serve low-quality images & videos Conditionally load heavier

    JS on fast devices Avoid computationally heavy operations Turn off or throttle Animations Block 3rd-party scripts on slower devices
  64. Make your site Lazy-First Reduce Defer Coalesce

  65. Design your site with inclusivity in mind

  66. Thank you! Addy Osmani Chrome @addyosmani Nate Schloss Facebook @n8schloss

    With special thanks to Anton Karlovskiy
  67. None