预加载的资源为什么会阻塞页面加载?
我在用link rel=”preload”预加载图片时发现页面反而更卡了,明明只是预加载下一屏的图片啊。我按照文档写了这样的代码:
document.querySelectorAll('.next-page-img').forEach(img => {
const link = document.createElement('link');
link.rel = 'preload';
link.href = img.src;
link.as = 'image';
document.head.appendChild(link);
});
但监控显示这些预加载请求占用了大量带宽,导致主页CSS/JS加载延迟。我尝试过把priority设为low,但好像没效果。难道preload会默认高优先级?那应该怎么实现不阻塞主线程的资源预取呢?
你遇到的情况很常见,preload 本质上是“提前加载当前页可能需要的资源”,而并非专门用于后台静默加载。所以即使你设置了 priority 为 low,在浏览器实现层面,它可能依然没有被当作低优先级处理。
如果你只是想提前加载下一页或懒加载图片,可以考虑使用更轻量的 prefetch:
prefetch 的优先级比 preload 低很多,更适合后台预取资源,不会和首屏关键请求竞争带宽。preload 更适合字体、关键 CSS、JS 的预加载。
preload这玩意儿确实挺坑的,它本质上就是告诉浏览器“嘿,这个资源很重要,赶紧去加载”。虽然你写了as='image',但浏览器还是会把它当成高优先级的东西来处理,默认分配较多的带宽资源。这就是为什么你的图片预加载会挤占主页CSS/JS的加载带宽。问题的关键在于,
preload本身并没有真正意义上的“低优先级”选项。即使你加了priority=low,很多浏览器根本不会理会这个属性,因为它不是标准的一部分。如果你想实现不阻塞主线程的资源预取,可以考虑用
代替。prefetch的设计初衷就是用于稍后可能需要的资源,它的优先级非常低,不会抢占关键资源的带宽。代码改一下就行:
不过要注意,
prefetch是等到页面空闲时才会触发加载,所以如果你希望更精细地控制,也可以直接用fetch手动下载图片到内存:最后提醒一句,别乱预加载太多东西,否则照样会影响用户体验。预加载是个技术活儿,得根据实际需求权衡。