Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Deliver experiences best suited to a user's device and network constraints

License

NotificationsYou must be signed in to change notification settings

GoogleChromeLabs/react-adaptive-hooks

Repository files navigation

Deliver experiences best suited to a user's device and network constraints (experimental)

This is a suite ofReact Hooks and utilities for adaptive loading based on a user's:

It can be used to add patterns for adaptive resource loading, data-fetching, code-splitting and capability toggling.

Objective

Make it easier to target low-end devices while progressively adding high-end-only features on top. Using these hooks and utilities can help you give users a great experience best suited to their device and network constraints.

Installation

npm i react-adaptive-hooks --save oryarn add react-adaptive-hooks

Usage

You can import the hooks you wish to use as follows:

import{useNetworkStatus}from'react-adaptive-hooks/network';import{useSaveData}from'react-adaptive-hooks/save-data';import{useHardwareConcurrency}from'react-adaptive-hooks/hardware-concurrency';import{useMemoryStatus}from'react-adaptive-hooks/memory';import{useMediaCapabilitiesDecodingInfo}from'react-adaptive-hooks/media-capabilities';

and then use them in your components. Examples for each hook and utility can be found below:

Network

useNetworkStatus React hook for adapting based on network status (effective connection type)

importReactfrom'react';import{useNetworkStatus}from'react-adaptive-hooks/network';constMyComponent=()=>{const{ effectiveConnectionType}=useNetworkStatus();letmedia;switch(effectiveConnectionType){case'slow-2g':media=<imgsrc='...'alt='low resolution'/>;break;case'2g':media=<imgsrc='...'alt='medium resolution'/>;break;case'3g':media=<imgsrc='...'alt='high resolution'/>;break;case'4g':media=<videomutedcontrols>...</video>;break;default:media=<videomutedcontrols>...</video>;break;}return<div>{media}</div>;};

effectiveConnectionType values can beslow-2g,2g,3g, or4g.

This hook accepts an optionalinitialEffectiveConnectionType string argument, which can be used to provide aeffectiveConnectionType state value when the user's browser does not support the relevantNetworkInformation API. Passing an initial value can also prove useful for server-side rendering, where the developer can pass anECT Client Hint to detect the effective network connection type.

// Inside of a functional React componentconstinitialEffectiveConnectionType='4g';const{ effectiveConnectionType}=useNetworkStatus(initialEffectiveConnectionType);

Save Data

useSaveData utility for adapting based on the user's browser Data Saver preferences.

importReactfrom'react';import{useSaveData}from'react-adaptive-hooks/save-data';constMyComponent=()=>{const{ saveData}=useSaveData();return(<div>{saveData ?<imgsrc='...'/> :<videomutedcontrols>...</video>}</div>);};

saveData values can betrue orfalse.

This hook accepts an optionalinitialSaveData boolean argument, which can be used to provide asaveData state value when the user's browser does not support the relevantNetworkInformation API. Passing an initial value can also prove useful for server-side rendering, where the developer can pass a serverSave-Data Client Hint that has been converted to a boolean to detect the user's data saving preference.

// Inside of a functional React componentconstinitialSaveData=true;const{ saveData}=useSaveData(initialSaveData);

CPU Cores / Hardware Concurrency

useHardwareConcurrency utility for adapting to the number of logical CPU processor cores on the user's device.

importReactfrom'react';import{useHardwareConcurrency}from'react-adaptive-hooks/hardware-concurrency';constMyComponent=()=>{const{ numberOfLogicalProcessors}=useHardwareConcurrency();return(<div>{numberOfLogicalProcessors<=4 ?<imgsrc='...'/> :<videomutedcontrols>...</video>}</div>);};

numberOfLogicalProcessors values can be the number of logical processors available to run threads on the user's device.

Memory

useMemoryStatus utility for adapting based on the user's device memory (RAM)

importReactfrom'react';import{useMemoryStatus}from'react-adaptive-hooks/memory';constMyComponent=()=>{const{ deviceMemory}=useMemoryStatus();return(<div>{deviceMemory<4 ?<imgsrc='...'/> :<videomutedcontrols>...</video>}</div>);};

deviceMemory values can be the approximate amount of device memory in gigabytes.

This hook accepts an optionalinitialMemoryStatus object argument, which can be used to provide adeviceMemory state value when the user's browser does not support the relevantDeviceMemory API. Passing an initial value can also prove useful for server-side rendering, where the developer can pass a serverDevice-Memory Client Hint to detect the memory capacity of the user's device.

// Inside of a functional React componentconstinitialMemoryStatus={deviceMemory:4};const{ deviceMemory}=useMemoryStatus(initialMemoryStatus);

Media Capabilities

useMediaCapabilitiesDecodingInfo utility for adapting based on the user's device media capabilities.

Use case: this hook can be used to check if we can play a certain content type. For example, Safari does not support WebM so we want to fallback to MP4 but if Safari at some point does support WebM it will automatically load WebM videos.

importReactfrom'react';import{useMediaCapabilitiesDecodingInfo}from'react-adaptive-hooks/media-capabilities';constwebmMediaDecodingConfig={type:'file',// 'record', 'transmission', or 'media-source'video:{contentType:'video/webm;codecs=vp8',// valid content typewidth:800,// width of the videoheight:600,// height of the videobitrate:10000,// number of bits used to encode 1s of videoframerate:30// number of frames making up that 1s.}};constinitialMediaCapabilitiesInfo={powerEfficient:true};constMyComponent=({ videoSources})=>{const{ mediaCapabilitiesInfo}=useMediaCapabilitiesDecodingInfo(webmMediaDecodingConfig,initialMediaCapabilitiesInfo);return(<div><videosrc={mediaCapabilitiesInfo.supported ?videoSources.webm :videoSources.mp4}controls>...</video></div>);};

mediaCapabilitiesInfo value contains the three Boolean properties supported, smooth, and powerEfficient, which describe whether decoding the media described would be supported, smooth, and powerEfficient.

This utility accepts aMediaDecodingConfiguration object argument and an optionalinitialMediaCapabilitiesInfo object argument, which can be used to provide amediaCapabilitiesInfo state value when the user's browser does not support the relevantMedia Capabilities API or no media configuration was given.

Adaptive Code-loading & Code-splitting

Code-loading

Deliver a light, interactive core experience to users and progressively add high-end-only features on top, if a user's hardware can handle it. Below is an example using the Network Status hook:

importReact,{Suspense,lazy}from'react';import{useNetworkStatus}from'react-adaptive-hooks/network';constFull=lazy(()=>import(/* webpackChunkName: "full" */'./Full.js'));constLight=lazy(()=>import(/* webpackChunkName: "light" */'./Light.js'));constMyComponent=()=>{const{ effectiveConnectionType}=useNetworkStatus();return(<div><Suspensefallback={<div>Loading...</div>}>{effectiveConnectionType==='4g' ?<Full/> :<Light/>}</Suspense></div>);};exportdefaultMyComponent;

Light.js:

importReactfrom'react';constLight=({ imageUrl, ...rest})=>(<imgsrc={imageUrl}{...rest}/>);exportdefaultLight;

Full.js:

importReactfrom'react';importMagnifierfrom'react-magnifier';constFull=({ imageUrl, ...rest})=>(<Magnifiersrc={imageUrl}{...rest}/>);exportdefaultFull;

Code-splitting

We can extendReact.lazy() by incorporating a check for a device or network signal. Below is an example of network-aware code-splitting. This allows us to conditionally load a light core experience or full-fat experience depending on the user's effective connection speed (vianavigator.connection.effectiveType).

importReact,{Suspense}from'react';constComponent=React.lazy(()=>{consteffectiveType=navigator.connection ?navigator.connection.effectiveType :nullletmodule;switch(effectiveType){case'3g':module=import(/* webpackChunkName: "light" */'./Light.js');break;case'4g':module=import(/* webpackChunkName: "full" */'./Full.js');break;default:module=import(/* webpackChunkName: "full" */'./Full.js');break;}returnmodule;});constApp=()=>{return(<divclassName='App'><Suspensefallback={<div>Loading...</div>}><Component/></Suspense></div>);};exportdefaultApp;

Server-side rendering support

The built version of this package uses ESM (native JS modules) by default, but is not supported on the server-side. When using this package in a web framework like Next.js with server-rendering, we recommend you

import {  useNetworkStatus,  useSaveData,  useHardwareConcurrency,  useMemoryStatus,  useMediaCapabilitiesDecodingInfo} from 'react-adaptive-hooks/dist/index.umd.js';

Browser Support

Demos

Network

Save Data

CPU Cores / Hardware Concurrency

Memory

Hybrid

References

License

Licensed under the Apache-2.0 license.

Team

This project is brought to you byAddy Osmani andAnton Karlovskiy.

About

Deliver experiences best suited to a user's device and network constraints

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors11


[8]ページ先頭

©2009-2025 Movatter.jp