网络差的时候怎么智能预加载资源?

文阁 阅读 37

我在做移动端页面优化,想根据用户的网络状态决定是否预加载下一页的图片。用了 navigator.connection.effectiveType 判断,但在低端机上效果不稳定,有时网速明明很慢却还是触发了预加载,导致卡顿。

我试着用 CSS 的 media query 配合 prefers-reduced-data,但好像没生效?比如下面这段:

@media (prefers-reduced-data: reduce) {
  .preload-image {
    display: none;
  }
}

是不是这个特性支持太差?有没有更靠谱的 JS + 网络感知的预加载方案?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
Newb.海淇
navigator.connection.effectiveType 确实有时候不太靠谱,特别是在低端设备上,波动挺大的。prefers-reduced-data 这个媒体查询的支持情况也不理想,很多用户根本不会去设置它。

一个相对靠谱的做法是结合网络状态检测和用户行为来判断是否预加载资源。可以先用 navigator.connection.effectiveType 做初步判断,然后结合用户滚动行为来决定是否真的开始预加载。比如说,当用户快速滚动页面时,即使网络状态显示还可以,也可以考虑延迟或不预加载。

这里有一个简单的实现思路:

1. 使用 navigator.connection.effectiveType 来判断当前网络类型。
2. 监听用户的滚动事件,判断用户的行为模式。
3. 结合这两个信息来决定是否预加载。

下面是一个简单的代码示例:

pre class="pure-highlightjs line-numbers">
let shouldPreload = true;

// 初步判断网络类型
if ('connection' in navigator) {
if (navigator.connection.effectiveType === 'slow-2g' || navigator.connection.effectiveType === '2g') {
shouldPreload = false;
}
}

// 监听滚动事件
window.addEventListener('scroll', function() {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.scrollHeight;

// 用户接近页面底部时触发预加载
if (scrollTop + windowHeight >= documentHeight - 100 && shouldPreload) {
preloadImages();
}
});

function preloadImages() {
// 这里写具体的预加载逻辑
console.log('Preloading images...');
}


这种方法虽然不是完美的,但至少可以在一定程度上改善用户体验,避免在网络差的情况下进行不必要的资源加载。记得测试各种场景下的表现,不断调整策略。
点赞
2026-03-23 20:16
熙恩
熙恩 Lv1
移动端网络检测确实是个头疼的问题,navigator.connection确实不太靠谱,特别是一些国产定制ROM。prefers-reduced-data的支持度更惨,目前基本就是个摆设。

我建议搞个更实在的混合方案:
1. 先用navigator.connection.effectiveType做初步判断
2. 自己实现个简单的网络测速,比如用一个小文件做下载测速
3. 结合历史网络状况做决策

给个实际的代码示例:
let lastSpeed = 0;
const testFileUrl = 'https://your-cdn.com/small-test-file.jpg';

async function checkNetworkSpeed() {
try {
const start = Date.now();
const res = await fetch(testFileUrl, {cache: 'no-store'});
const blob = await res.blob();
const speed = blob.size / ((Date.now() - start) / 1000);

// 平滑处理
lastSpeed = lastSpeed ? (lastSpeed * 0.7 + speed * 0.3) : speed;
return lastSpeed;
} catch(e) {
console.error('测速失败', e);
return 0;
}
}

// 使用示例
const speed = await checkNetworkSpeed();
if(speed > 500 * 1024) { // 大于500KB/s才预加载
preloadImages();
}


几个实践经验:
1. 测速文件要小(建议50-100KB),放CDN上
2. 加个缓存策略避免频繁测速
3. 对于特别低端的设备,可以直接用内存/CPU信息兜底判断
4. 记得加个最大重试次数,别卡死在测速上

这套方案我们在海外项目实测过,比单纯用API靠谱多了。虽然要多发个请求,但总比把用户搞卡死强。
点赞
2026-03-09 22:03