如何根据网络状态动态调整预加载策略?

UX玉曼 阅读 14

我在做图片懒加载时想结合网络感知,比如在 4G/5G 下多预加载几张,WiFi 下全量加载,但 navigator.connection 好像兼容性不太好?

试过用 navigator.connection.effectiveType 判断,但在 iOS Safari 上直接 undefined,有没有更稳妥的方案?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
端木俊衡
哎,这个问题我之前也踩过坑!iOS Safari 确实不支持 Network Information API,而且就算支持的浏览器,返回值也不一定准确,毕竟 effectiveType 只是个估算值。

我现在的做法是分三层来做兼容:

第一层,先用特性检测,有 API 就用,没有就降级。代码大概这样:

function getNetworkType() {
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;

if (connection && connection.effectiveType) {
return connection.effectiveType;
}
return 'unknown';
}

function getPreloadCount() {
const type = getNetworkType();

if (type === '4g' || type === '5g') {
return 5;
} else if (type === '3g') {
return 2;
} else if (type === '2g' || type === 'slow-2g') {
return 1;
}
// unknown 或者不支持的情况,默认保守策略
return 2;
}


第二层,监听网络变化,这个 API 在支持的浏览器上挺好用的:

const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;

if (connection) {
connection.addEventListener('change', () => {
// 网络状态变了,重新调整预加载策略
updatePreloadStrategy();
});
}


第三层,也是我觉得最靠谱的方案,自己测速。发一个小请求计算耗时,这样不依赖浏览器 API,而且能反映用户的真实网络质量:

async function measureNetworkSpeed() {
const testUrl = '/static/test-image.jpg?t=' + Date.now(); // 防缓存
const startTime = performance.now();

try {
await fetch(testUrl, { method: 'HEAD' });
const endTime = performance.now();
const duration = endTime - startTime;

// 根据耗时判断,这个阈值可以根据业务调整
if (duration < 100) return 'fast'; // WiFi/5G
if (duration < 300) return 'medium'; // 4G
if (duration < 800) return 'slow'; // 3G
return 'very-slow';
} catch (e) {
return 'unknown';
}
}


我建议把这两个方案结合起来用:先检查 navigator.connection,没有或者 undefined 的时候就用测速方案兜底。虽然多了一次请求,但胜在稳定可靠。

对了,还有个细节要注意,测速不要太频繁,我一般会在 sessionStorage 里缓存一下结果,设置个 5 分钟过期时间,不然用户每翻一页都测一次也挺烦的。
点赞 2
2026-03-01 14:02