省流不能仅依赖 navigator.connection.saveData 判定——它只是信号,必须在 HTML 解析早期拦截资源请求;需三步判空防报错,内联脚本须置于 <head> 顶部,CSS 隐藏不阻请求,须 JS 主动降级资源、禁用非关键脚本及 API 路由。

不能只靠 navigator.connection.saveData 就认为省流已生效——它只是个信号,真正省流必须在 HTML 解析阶段就拦截资源请求,否则图片、字体、第三方脚本早已发出。
如何安全读取 saveData 而不触发 JS 错误
直接写 navigator.connection.saveData 在 Safari、旧版 WebView 或 iframe 环境中会报 Cannot read property 'saveData' of null。必须分三步判空:
- 检查
"connection" in navigator - 确认
navigator.connection !== null - 再验证
"saveData" in navigator.connection
漏掉任一环,线上就可能中断 JS 执行。别用 !!navigator.connection?.saveData —— 因为未开启时它可能是 undefined,而未来规范若允许字符串值(如 "on"),这种写法会失效。
为什么内联脚本必须放在 <head> 早期执行
等 DOMContentLoaded 或 React 的 useEffect 触发时,<img src>、<link rel="preload">、字体文件甚至统计脚本都已发起请求。省流动作已经晚了。
立即学习“前端免费学习笔记(深入)”;
正确做法是:在 <head> 中紧贴 <meta charset> 后插入一段无 async、无 defer 的内联 <script>:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
<script>
if ("connection" in navigator && navigator.connection !== null && "saveData" in navigator.connection) {
if (navigator.connection.saveData) {
document.documentElement.classList.add("save-data");
}
}
</script>
这样 CSS 规则(如 html.save-data img { display: none; })能立即生效,避免重排重绘,但注意:这仅控制样式,不阻止请求。
仅加 class 不等于省流:必须主动拦截资源加载
html.save-data img { display: none; } 只是视觉隐藏,src 仍会下载——流量照跑。真正省流要 JS 层面干预:
- 把懒加载图片的
loading="lazy"改为eager,并切换到低分辨率源:img.src = img.dataset.lowres || img.src - 跳过 WebP/AVIF 格式协商,强制用
jpg或svg:<picture>中删掉type="image/webp"分支 - 禁用非关键脚本:当
navigator.connection.saveData为true时,跳过loadAnalytics()、initRecommendEngine()等调用 - API 请求路由降级:
fetch(navigator.connection.saveData ? "/api/light" : "/api/full")
这些逻辑不能靠 CSS class 反向推导,必须显式判断 navigator.connection.saveData。
兼容性兜底和常见误判点
Safari(iOS 14.5+ / macOS 11.3+)才支持 saveData,旧版返回 undefined;Chrome 和 Edge 支持较好;Firefox 已弃用该 API;多数桌面浏览器和 WebView 中 navigator.connection 为空对象或根本不存在。
别把 navigator.connection.type === "cellular" 当作省流依据——5G 下也可能是 "cellular";也别依赖 prefers-reduced-data 媒体查询,它至今未被任何主流浏览器实现。
真正容易被忽略的是:这个值不会动态更新。用户中途开关省流模式时,saveData 不会触发 change 事件,前端无法实时响应。所以首次检测后,应结合 visibilitychange + 轮询(极低频)做有限补救,但不要指望它替代服务端决策。

















