图片预加载不是“越多越快”,而需在用户无感、浏览器不卡、缓存真复用三者间求平衡;盲目预加载会拖慢首屏、浪费流量、引发CORS或内存溢出。

什么时候该用预加载,而不是懒加载
预加载(preload)适用于「用户几乎必然看到」的资源,比如首页 Banner 图、登录页头像占位图、商品详情页主图;懒加载(loading="lazy" 或 IntersectionObserver)适用于「可能滚动才进入视口」的内容,比如长列表中的商品缩略图。
常见误判:
- 把整个商品列表的 50 张图都
preload→ 浏览器并发请求打满,首屏渲染阻塞 - 对用户 80% 概率不会点进的二级页面图做预加载 → 白跑请求,缓存未命中
- 在
DOMContentLoaded后才开始预加载 → 失去“提前进缓存”的意义,等同于普通加载
link[rel="preload"] 的实际限制和绕过方法
原生 <link rel="preload"> 只支持提前声明,不能动态控制加载时机或失败回调,且不支持跨域资源(除非服务端配了 Access-Control-Allow-Origin)。
可行替代方案:
- 关键图用
<link rel="preload" as="image" href="hero.jpg">放在<head>—— 必须确保路径稳定、无重定向、非 CDN 域名跳变 - 动态图用
new Image()实例 +onload/onerror:更可控,可批量、可降级、可记录失败率 - 避免用
XMLHttpRequest预加载图片:会触发 CORS、不进 HTTP 缓存、无法复用解码后的 bitmap
预加载后图片没被复用?检查这三个地方
预加载成功 ≠ 页面显示时真从缓存取。常因以下原因失效:
- URL 字符串不完全一致:查询参数顺序不同(
img.jpg?w=300&h=200vsimg.jpg?h=200&w=300)、大小写差异、末尾斜杠有无 - 响应头禁止缓存:
Cache-Control: no-store或Expires: past会让预加载白做 - 图片被 CSS
background-image引用但路径拼接出错:比如 JS 拼了/img/前缀,而 CSS 里写的是相对路径./banner.jpg
验证是否复用:打开 DevTools → Network → 找到预加载的图片请求 → 看 Size 列是否为 from cache 或 memory cache。

















