配了三年性能优化,今天发现浏览器自己会「看网速」了——navigator.connection把网络感知彻底还给了前端
判断用户网快还是网慢,这件事以前要么靠后端回报、要么靠前端盲猜。但浏览器其实早就有这个能力了,大多数人没用过——navigator.connection 这个接口,把网络感知彻底做进了平台层。
这三个值,才是真正的「网速」
navigator.connection 不是给你一个「快/慢」的结论,而是给三个原始值,你自己定阈值:
const conn = navigator.connection;
console.log(conn.rtt); // 往返延迟 ms,四舍五入到 25 的倍数
console.log(conn.downlink); // 预估下行带宽 Mbps
console.log(conn.effectiveType); // 'slow-2g' | '2g' | '3g' | '4g'
注意 effectiveType 不是简单看网络类型(WiFi/4G),而是综合了最近观测到的 rtt 和 downlink 得出的实际效能评级。所以同样是 4G 信号,在地铁里和在开阔地带,effectiveType 可能完全不同。
rtt 返回的是毫秒数,四舍五入到 25 的倍数——比如你实测 63ms,返回的是 50ms;93ms 返回的是 75ms。这不是精度低,是 API 设计上不给你虚假精确。
实战一:图片自动适配
最直接的应用,根据网速选图片规格:
function getImageSrc() {
const { effectiveType, downlink } = navigator.connection;
if (effectiveType === 'slow-2g' || effectiveType === '2g') {
return '/img/thumb.jpg'; // 弱网:只加载缩略图
}
if (effectiveType === '3g' || downlink < 4) {
return '/img/medium.jpg'; // 中等网速
}
if (downlink >= 10) {
return '/img/hd.avif'; // 千兆宽带有保障,上高清
}
return '/img/medium.jpg';
}
// 监听网络变化,用户从 WiFi 切到流量自动重新选图
navigator.connection.addEventListener('change', () => {
document.querySelector('img').src = getImageSrc();
});
实战二:视频自动降码
视频场景比图片更有价值,码率差距直接对应流量账单:
function getVideoQuality() {
const { effectiveType, rtt } = navigator.connection;
if (effectiveType === 'slow-2g' || rtt > 500) {
return '360p';
}
if (effectiveType === '2g' || rtt > 300) {
return '480p';
}
if (effectiveType === '3g') {
return '720p';
}
return '1080p+'; // 4G 及以上全开
}
把码率决策从前端硬编码搬到浏览器真实数据,弱网用户不会被 1080p 视频卡死,流量也省了。
实战三:省流模式
Chrome 还给了一个更直接的信号——saveData:
navigator.connection.addEventListener('change', () => {
if (navigator.connection.saveData) {
// 开启省流模式:不加载非关键图片、关闭动效、默认文字版
document.body.classList.add('reduced-data');
}
});
这个是用户在系统层面主动开启的,比你自己猜用户想要什么准多了。
Safari 的坑
这个 API 有个现实问题——Safari 完全不支持。MDN 的 Baseline 表格里它是 “Limited availability”,主要就 Chrome/Edge 用。所以适合作为渐进增强来用,而不是唯一判断路径:
function adaptiveLoad() {
if (!navigator.connection) {
// 兜底:全部加载,让用户自己决定
loadDefault();
return;
}
const { effectiveType } = navigator.connection;
if (effectiveType === 'slow-2g' || effectiveType === '2g') {
loadLite();
} else {
loadFull();
}
}
弱网环境基本上不会是 Safari 用户——Safari 用户通常在 iOS 上,网速本身不差;真正在 2G/3G 环境里的主要是安卓低端机和部分地区用户。了解这个分布,做决定就不纠结了。
写在最后
navigator.connection 本质上解决的是一个问题:你的代码知道不知道当前网络状况。能知道,就能做智能决策;不知道,就只能要么全量加载赌用户网好,要么保守加载牺牲体验。
三个值记住就够了:rtt 是延迟、downlink 是带宽、effectiveType 是综合评级。网络感知这件事,浏览器已经帮你把基础设施建好了,剩下的看你怎么用。
下一步:找一个你现在项目里做网络判断的地方,把 navigator.connection 嵌进去试一下。数据比感觉准。
评论区
登录后可评论。