【序】今天阅读到一篇公众号,讲的是性能自适应,这让我感到好奇,那么就一起来看看这个性能自适应该如何做吧,原文,原文中有表达不清晰的地方,查阅了MDN文档,做了些补充
问题一
- 【疑惑】:什么是性能自适应,以及自适应的使用场景?
- 【解惑】:自适应比较容易理解的就是如果是2G网络那么就展示一张图片,如果是4G那么就可以展示一个播放器,或者针对小内存的用户,或内存所剩无几的机器。性能自适应通常用在用在适配一些低端机型和欠网络的地方,虽然在我国网络发达的大国不是很关注这方面,但是在印度或者其它欠发达地区,emm你懂的,所以如果是国际性的项目的话,做一定的性能自适应还是有必要的。
问题二
- 【疑惑】:如何开始呢?
- 【解惑】:主要就是实现以下步骤
- 为所有用户(包括低端设备)提供快速良好的使用体验
- 在用户的网络和硬件能够处理的情况下,逐步增加高端功能。
- 【关键】:自适应首先是两个步骤,1. 判断,2. 展示,
问题三
- 【疑惑】:如何判断呢?
- 【解惑】:chrome中提供了判断手机性能的api,统称为Network Information API,该API由networkInformation大类组成,但是该类并不能调用,chrome端能调用的是navigator.connection,一部分是,以下是主要功能
- 判断网络:
navigator.connection.effectiveType
// "2g"|"3g"|"4g" - 判断单内存总量:
navigator.deviceMemory
// 8 在PC端表示单条内存条的总数,我的单条内存是8G,不会剔除已经使用的内存 - 判断CPU核数:
navigator.hardwareConcurrency
// 6 (以核为单位) - 判断下载带宽:
navigator.downlink
//1.7 有效带宽估计值(以兆比特/秒为单位) - 判断数据节约:
navigator.saveData
// false 如果用户在用户代理上设置了减少数据使用量选项就会返回true - 判断当前网络的延迟:
navigator.rtt
// 170 返回当前连接的估计有效往返时间(以毫秒为单位)
我们还需要关注一下该api的兼容性
Network Information API 兼容性
问题四
- 【疑惑】:怎么去实现呢?
- 【解惑】:具体实现可以根据不同的框架进行封装,这里提供一个react的项目仅供参考
// react-adaptive-hooks 项目地址https://github.com/GoogleChromeLabs/react-adaptive-hooks
import React from 'react';
import { useNetworkStatus } from 'react-adaptive-hooks/network';
const MyComponent = () => {
const { effectiveConnectionType } = useNetworkStatus();
let media;
switch(effectiveConnectionType) {
case '2g':
media = <img src='medium-res.jpg'/>;
break;
case '3g':
media = <img src='high-res.jpg'/>;
break;
case '4g':
media = <video muted controls>...</video>;
break;
default:
media = <video muted controls>...</video>;
break;
}
return <div>{media}</div>;
};
import React from 'react';
import { useSaveData } from 'react-adaptive-hooks/save-data';
const MyComponent = () => {
const { saveData } = useSaveData();
return (
<div>
{ saveData ? <img src='...' /> : <video muted controls>...</video> }
</div>
);
};
import React from 'react';
import { useHardwareConcurrency } from 'react-adaptive-hooks/hardware-concurrency';
const MyComponent = () => {
const { numberOfLogicalProcessors } = useHardwareConcurrency();
return (
<div>
{ numberOfLogicalProcessors <= 4 ? <img src='...' /> : <video muted controls>...</video> }
</div>
);
};