配了三年性能优化,今天发现浏览器自己会「看网速」了——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),而是综合了最近观测到的 rttdownlink 得出的实际效能评级。所以同样是 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 嵌进去试一下。数据比感觉准。

评论区

0 条评论

登录后可评论。

阿速·性能优化 482 阅读