Device capabilities and network connections vary a lot. Sites that delight users
on high-end devices can be
unusable on low-end ones. Sites
that load smoothly on fast networks can come to a halt on slow ones. Any user
can experience a slow website, that’s why developing “one-size fits all”
solutions may not always work.
In their Chrome Dev Summit talk,
Addy Osmani from Google and Nate Schloss from Facebook explore a solution to that problem—a
pattern for delivering pages that better cater to a variety of user
constraints. They call it adaptive loading.
What is adaptive loading?
Adaptive loading involves delivering different experiences to different users
based on their network and hardware constraints, specifically:
A fast core experience for all users (including low-end devices).
Progressively adding high-end-only features, if a user’s network and hardware
can handle it.
By optimizing for specific hardware and network constraints you enable every
user to get the best possible experience for their device. Tailoring the
experience to users’ constraints can include:
Serving low-quality images and videos on slow networks.
Throttling the frame-rate of animations on low-end devices.
Avoiding computationally expensive operations on low-end devices.
Blocking third-party scripts on slower devices.
How to implement adaptive loading
The signals you can use for adaptive loading are:
There are two places where you can make a decision about what to serve to users:
above. On the server, you can use client
to get insight into the user’s device capabilities and the network they’re
Adaptive loading in React
React Adaptive Loading Hooks &
Utilities is a suite
for the React ecosystem that makes it easier to adapt your sites to lower-end
devices. It includes:
useNetworkStatus()hook for adapting based on network status (
useSaveData()hook for adapting based on the user’s Data Saver
useHardwareConcurrency()hook for adapting based on the number of
logical CPU processor cores on the user’s device.
useMemoryStatus()hook for adapting based on the user’s device memory
Each hook accepts an optional argument for setting the initial value. This
option is useful in two scenarios: when the user’s browser does not support the
relevant API and for server-side rendering where you can use the client hint
data to set the initial value on the server. For example, the
useNetworkStatus() hook can use the initial value passed from client hint for
server-side rendering and, when executed on the client, update itself if the
network effective type changes.
React Adaptive Loading Hooks & Utilities are implemented using web platform APIs
You can use the same APIs to apply adaptive loading concepts to other frameworks
and libraries, such as
Adaptive loading in action
This section explores demos of how you could use adaptive loading and real-world
examples from sites such as Facebook, eBay, Tinder, and others.
shows how to adapt media serving based on the network
It’s an application for browsing movies that shows posters, summaries, and cast
lists. Based on the user’s effective connection type, it serves high-quality
posters on fast connections and low-quality posters on slow ones.
Twitter has a Data Saver
mode designed to
reduce the amount of data used. In this mode, preview images load in
low-resolution and large images load only when you tap on the preview. With this
option enabled, users on iOS and Android saved 50% in data-usage from images,
and users on the web saved 80%. Here’s a React
that uses the Save Data hook to replicate the Twitter timeline. Try
opening your DevTools Network panel and looking at the difference in the amount
of data transferred as you scroll while Save Data is disabled versus when it’s
eBay conditionally turns on and off features like zooming when a user’s hardware
or network conditions don’t support them well. You can achieve this through
adaptive code-splitting and
code loading—a way to conditionally load more highly interactive components or
run more computationally heavy operations on high-end devices, while not sending
those scripts down to users on slower devices. Check out the video at 16
mins where Addy shows this pattern
implemented with React.lazy() and Suspense on a
demo eBay product
Tinder is using a number of adaptive loading patterns in its
and Lite app to keep the
experience fast for everyone. If a user is on a slow network or has Data Saver
enabled, they disable video autoplay, limit route prefetching
and limit loading the next image in the carousel to loading images one at a time
as users swipe. After implementing these optimizations, they’ve seen significant
improvements in average swipe count in countries such as Indonesia.
Adaptive loading at Facebook
One issue that comes up in adaptive loading is grouping devices into high-end
and low-end classes based on available signals. On mobile devices the
user-agent (UA) string
provides the device name which enables Facebook to use publicly available data
on device characteristics to group mobile devices into classes. However, on
desktop devices the only relevant information the UA provides is the device’s
For grouping desktop devices, Facebook logs the data about the operating system,
CPU cores (from
navigator.hardwareConcurrency), and RAM memory
navigator.deviceMemory) in their performance monitoring. Looking at the
relationships between different types of hardware and performance, they
classified devices into five categories. With hardware classes integrated into
performance monitoring, they get a more complete picture of how people use
Facebook products depending on their device and can identify regressions more
Check out the video at 24 mins, where
Nate walks through how Facebook approaches device grouping and uses adaptive
Learn more about adaptive loading
Adaptive loading is all about designing your sites with inclusivity in mind.
Build a core experience that works great for everyone, then toggle or layer
features that make it even more awesome if a user has enough memory, CPU, or a
fast network. To learn more about adaptive loading, check out the available
and watch the Chrome Dev Summit talk: