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

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

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

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

    View Slide

  2. Any user can have a slow
    experience.

    View Slide

  3. View Slide

  4. View Slide

  5. Respect the user’s
    and

    View Slide

  6. Smartphone hardware varies
    CPU
    Memory
    Storage
    Screen
    Battery

    View Slide

  7. The Performance Gap On Mobile
    src: IHS Markit Smartphone Model Market Tracker 2019H + Geekbench V4

    View Slide

  8. If you want to build a fast site,
    use slow hardware

    View Slide

  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

    View Slide

  10. Do we need to deliver the
    exact same experience to
    every user?

    View Slide

  11. Adaptive Loading

    View Slide

  12. Demo

    View Slide

  13. Demo
    Open demo

    View Slide

  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

    View Slide

  15. Adaptive Loading
    React Hooks
    bit.ly/react-adaptive
    Experimental

    View Slide

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

    View Slide

  17. Home Products Product
    Item Component media
    Fast
    Adaptive Media Loading
    Slow Median
    Connection:

    View Slide

  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 = ; break;
    case '4g':
    media = ;
    break;

    View Slide

  19. Demo
    Open demo

    View Slide

  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 (

    { saveData ? : }

    View Slide

  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%

    View Slide

  22. Demo
    Open demo
    WPT

    View Slide

  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

    View Slide

  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 (

    { deviceMemory < 4 ? : }

    View Slide

  25. Demo
    Open demo

    View Slide

  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

    View Slide

  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

    View Slide

  28. import React, { Suspense } from 'react';
    const Sample = React.lazy(() => import('./Sample'));
    function MyComponent() {
    return (

    Loading...}>



    );
    }
    React.lazy() and Suspense

    View Slide

  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;

    View Slide

  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.

    View Slide

  31. Demo
    Open demo

    View Slide

  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 (
    { numberOfLogicalProcessors <= 4 ?
    : }

    View Slide

  33. Home Products Product
    Fast connection
    Slow connection
    Adaptive Data-fetching & Pre-fetching
    GraphQL server
    Database Database Database
    5 results 25 results

    View Slide

  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

    View Slide

  35. High-end
    Low-end
    Adaptive Capability Toggling
    Static
    Low frame-rate animation
    Full-fidelity animation
    High frame-rate

    View Slide

  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
    content="Device-Memory, Viewport-Width,
    Save-Data">
    Enable
    Added
    Response

    View Slide

  37. Demo
    Open demo

    View Slide

  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

    View Slide

  39. View Slide

  40. Do not just respond based on screen size,
    adapt based on actual device hardware

    View Slide

  41. Web device classification at Facebook

    View Slide

  42. Web device classification at Facebook
    Define buckets

    View Slide

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

    View Slide

  44. Web device classification at Facebook
    Define buckets
    Integrate buckets into logging
    Adapt loading based on buckets

    View Slide

  45. On mobile we get the device name in the UA,
    so we can use the year class concept.
    Grouping Hardware On Mobile

    View Slide

  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

    View Slide

  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...

    View Slide

  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

    View Slide

  49. Creating desktop
    hardware buckets

    View Slide

  50. 1) Log hardwareConcurrency and deviceMemory

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  54. When integrated
    into performance
    logging, hardware
    class reveals a more
    complete picture

    View Slide

  55. View Slide

  56. Adaptivity should be
    considered in your core
    frameworks

    View Slide

  57. Think about animations
    Low End
    High End

    View Slide

  58. Mobile Websites

    View Slide

  59. Load fast vs respond fast

    View Slide

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

    View Slide

  61. isInputPending

    View Slide

  62. Using consistent definitions
    for buckets in logging and
    adapting lets you easily see
    the full picture

    View Slide

  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

    View Slide

  64. Make your site Lazy-First
    Reduce
    Defer
    Coalesce

    View Slide

  65. Design your site with
    inclusivity in mind

    View Slide

  66. Thank you!
    Addy Osmani
    Chrome
    @addyosmani
    Nate Schloss
    Facebook
    @n8schloss
    With special thanks to Anton Karlovskiy

    View Slide

  67. View Slide