Slide 1

Slide 1 text

Addy Osmani Chrome @addyosmani Adaptive Loading Improving the UX for billions on low-end devices Nate Schloss Facebook @n8schloss

Slide 2

Slide 2 text

Any user can have a slow experience.

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Respect the user’s and

Slide 6

Slide 6 text

Smartphone hardware varies CPU Memory Storage Screen Battery

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Adaptive Loading

Slide 12

Slide 12 text

Demo

Slide 13

Slide 13 text

Demo Open demo

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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;

Slide 19

Slide 19 text

Demo Open demo

Slide 20

Slide 20 text

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 ? : }

Slide 21

Slide 21 text

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%

Slide 22

Slide 22 text

Demo Open demo WPT

Slide 23

Slide 23 text

.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

Slide 24

Slide 24 text

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 ? : }

Slide 25

Slide 25 text

Demo Open demo

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Home Products Product Item Component Image Viewer Zoom Carousel Image Viewer Low-end device High-end device Adaptive Code-splitting & Code-loading Core experience

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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;

Slide 30

Slide 30 text

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.

Slide 31

Slide 31 text

Demo Open demo

Slide 32

Slide 32 text

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 ? : }

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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 Enable Added Response

Slide 37

Slide 37 text

Demo Open demo

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

Web device classification at Facebook

Slide 42

Slide 42 text

Web device classification at Facebook Define buckets

Slide 43

Slide 43 text

Web device classification at Facebook Define buckets Integrate buckets into logging

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

“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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

• 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

Slide 49

Slide 49 text

Creating desktop hardware buckets

Slide 50

Slide 50 text

1) Log hardwareConcurrency and deviceMemory

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

1) Log hardwareConcurrency and deviceMemory 2) Group by hardwareConcurrency, deviceMemory and OS when looking at perf data 3) Figure out buckets based on groupings

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

Adaptivity should be considered in your core frameworks

Slide 57

Slide 57 text

Think about animations Low End High End

Slide 58

Slide 58 text

Mobile Websites

Slide 59

Slide 59 text

Load fast vs respond fast

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

isInputPending

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

Make your site Lazy-First Reduce Defer Coalesce

Slide 65

Slide 65 text

Design your site with inclusivity in mind

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

No content