应先三层检查:typeof navigator.connection !== 'undefined'、typeof navigator.connection.effectivetype === 'string'、navigator.connection.effectivetype !== 'unknown',任一不满足则返回 null 降级处理。

怎么判断 navigator.connection 是否可用并安全读取 effectiveType
不是所有浏览器都支持 navigator.connection,Safari 桌面版至今完全不支持,部分旧版 Android WebView 也返回 undefined。直接访问 navigator.connection.effectiveType 会报 TypeError: Cannot read property 'effectiveType' of undefined。
必须先做三层检查:
typeof navigator.connection !== 'undefined'typeof navigator.connection.effectiveType === 'string'-
navigator.connection.effectiveType !== 'unknown'(某些 Android 浏览器会返回这个值)
漏掉任一环,都可能在弱网设备上触发静默错误或降级失效。建议封装成工具函数:
function getNetworkType() {
const conn = navigator.connection ||
navigator.mozConnection ||
navigator.webkitConnection;
if (!conn || typeof conn.effectiveType !== 'string' || conn.effectiveType === 'unknown') {
return null; // 不支持或无法判断,交由 fallback 策略处理
}
return conn.effectiveType;
}
effectiveType 和 type 的区别到底在哪,该用哪个
connection.type 只反映物理连接方式:比如 'cellular' 表示正在用蜂窝网络,但无法区分是 2G 还是 5G;'wifi' 也不代表带宽一定高(比如连的是公共厕所的蹭网热点)。
connection.effectiveType 是浏览器综合近期带宽、RTT、丢包率等指标估算出的「体验等级」,返回值如 '4g'、'slow-2g',更贴近真实加载表现。它才是资源调度的可靠依据。
常见误用:
- 用
connection.type === 'cellular'就禁高清图 → 错,5G 用户会被误伤 - 看到
connection.type === 'wifi'就预加载全部 JS → 错,公共 Wi-Fi 延迟可能高达 800ms - 忽略
effectiveType的滞后性:它基于平滑算法,变化有秒级延迟,不适合做动画帧率切换
怎么结合 downlink 做带宽分级,而不是只看 effectiveType
effectiveType 只有 5 个离散值,而 connection.downlink 返回的是浮点数(单位 Mbps),更适合做细粒度阈值控制。比如:
downlink :极弱网,跳过所有图片 <code>fetch,只渲染 SVG 占位符0.5 :弱网,加载 <code>JPG(质量 60%)、禁用 WebP/AVIF-
downlink >= 4:可放心加载AVIF、Lottie、完整图表库
注意:downlink 是浏览器估算值,不是实时测速结果。它每几秒更新一次,且首次访问时可能为 0 或 undefined,需配合 change 事件监听和兜底逻辑。
别忘了同时检查 connection.saveData:如果为 true,即使 effectiveType === '4g',也应强制走压缩策略。
监听 change 事件时容易踩的坑
connection.addEventListener('change', handler) 看似简单,但实际部署中常出问题:
- 事件可能在页面初始化前就触发,导致 handler 没注册上 → 必须在
DOMContentLoaded之前注册 - handler 内部若触发 DOM 批量重绘(如批量替换
img.src),会卡顿 → 改用requestIdleCallback或节流 - 移动端切后台再切回时,
effectiveType可能不变,但实际网络已切换(比如从地铁 4G 切到办公室 Wi-Fi)→ 需搭配定时心跳检测(例如每 10s 重读一次) - 监听后未解绑:单页应用路由切换时,旧 handler 仍存活,造成内存泄漏和重复执行
最稳妥的做法是:注册监听 + 页面卸载时移除 + 初始化时立即读一次值,三者缺一不可。
真正难的不是读到值,而是把“估算值”转化成稳定、不抖动、不误伤的加载决策——这需要结合 saveData、rtt、用户交互状态(比如是否在滚动)一起判断,不能只盯一个字段。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











