preload不支持sizes,仅认href;必须放在head中、href与img的src或srcset中某项完全一致、img需有width/height,三者缺一不可。

preload 里不能用 sizes,它只认 href
link rel="preload" 是纯资源提示,不参与响应式计算。它没有 sizes 属性,也不理解 srcset 的匹配逻辑。你写 <link rel="preload" as="image" href="hero.jpg" sizes="(max-width: 768px) 100vw">,浏览器会直接忽略 sizes,甚至可能报解析警告。
真正起作用的只有 href —— 它必须指向一个**确定的、可立即下载的 URL**。如果你的响应式图是靠 srcset + sizes 动态选的,那就没法用 preload 精准预加载“某一张”,只能选一个最可能被用到的版本(比如桌面端 1200w 或移动端 480w)。
- 首屏 Banner 图建议预加载最大尺寸(如
/img/hero-1200w.webp),因为 Chrome 会缓存它,后续srcset中同 URL 的项直接复用 - 若用 WebP,记得 fallback 路径也要单独 preload(
<link rel="preload" as="image" href="hero.jpg">),否则 Safari 加载失败时没缓存可退 - 不要试图在
href里拼接 JS 变量或媒体查询结果——preload是 HTML 解析早期就执行的,此时 JS 还没跑
sizes 必须和 img 标签共存,且只对 img 有效
sizes 是 <img> 的专属属性,只在它身上生效。它告诉浏览器:“这张图在不同视口下大概占多宽”,配合 srcset 里的 w 描述符做匹配。它和 preload 没有绑定关系,但二者必须协同:你 preload 的那张图,得正好出现在 srcset 列表里,且 href 和 srcset 中对应项的路径**完全一致**(包括大小写、斜杠、查询参数)。
- 错误写法:
<link rel="preload" href="/img/hero@2x.webp">,但<img srcset="/img/hero@2x.webp 2x">—— 路径不等,缓存不共享,白 preload - 正确写法:
<link rel="preload" href="/img/hero-800w.webp" as="image">,且<img srcset="/img/hero-480w.webp 480w, /img/hero-800w.webp 800w" sizes="100vw"> -
sizes值本身不能含单位(如300px),必须是vw、rem或媒体查询组合
为什么首屏图 preload + sizes 配合不好就白忙
常见失效场景不是代码写错,而是浏览器“不认账”:Safari(尤其 iOS 16.3 及更早)看到 loading="lazy" 就跳过所有预加载逻辑;Chrome 若发现 <img> 缺 width/height,会放弃懒加载检测,导致你 preload 的图和实际渲染的图被当成两个资源。
立即学习“前端免费学习笔记(深入)”;
- 必须显式写
loading="eager"给首屏图,不能依赖默认值 -
width和height得在<img>上用内联属性,或 CSS 里用aspect-ratio+width: 100%,否则 Safari 直接降级为 eager 加载,preload失去意义 - 如果图藏在
<picture>里,preload得指向<source>匹配到的最终 URL,而不是<img>的srcfallback
真正要检查的三个硬性条件
别只盯着 preload 标签有没有写对。只要以下任一条件不满足,整个链路就断了:
-
<link rel="preload">必须放在<head>里,且在对应<img>出现之前(SSR 渲染后已输出,不能 JS 动态插入) -
href和<img>的src或srcset中某一项**字符串完全相等**(建议用绝对路径避免相对路径解析歧义) -
<img>必须有width和height,且不能被transform、position: absolute或display: none破坏布局推断能力
这些点漏掉任何一个,preload 就只是多发一次请求,起不到“秒出”效果。



















