HTTP/2 Push 与 rel="preload" 冲突时,应优先验证推送是否真正生效:检查 DevTools Network 面板中目标资源的 Initiator 是否为 push,响应头 Content-Type 与 preload 的 as 属性是否严格匹配(如 font/woff2 ↔ as="font"),若推送覆盖则可删除 preload,否则必须保留以保障首屏关键资源加载。

HTTP/2 Push 与 rel="preload" 冲突时怎么判断是否真需要 preload
HTTP/2 推送已启用时,再写 rel="preload" 不仅无效,还会在 Chrome Network 面板里显示为 pending/canceled —— 这是浏览器发现资源已被推送后主动丢弃预加载请求的明确信号。
真正要做的不是“加不加”,而是确认推送是否覆盖了目标资源:
- 检查服务器是否对
/fonts/inter.woff2等关键路径配置了 PUSH_PROMISE(Nginx/Envoy/Caddy 的 push 配置项) - 在 DevTools Network 面板筛选该资源,Initiator 列应为
push,而非preload或parser - 若资源确由推送送达,
rel="preload"标签可安全删除;若未被推送(比如动态生成的图片路径),才需保留
响应式图片预加载必须用 sizes 且和 img 完全一致
link 标签没有 imagesrcset 属性,这个写法纯属无效,浏览器直接忽略。想让预加载匹配实际渲染尺寸,唯一合法方式是:rel="preload" + as="image" + sizes + 单个 href。
sizes 值不是“选图逻辑”,而是帮浏览器估算当前视口宽度,决定是否发起这次预加载:
立即学习“前端免费学习笔记(深入)”;
- 如果页面中
img的sizes是"(max-width: 768px) 100vw, 50vw",那么link的sizes必须一模一样 - 填错会导致浏览器误判宽度,该加载时不加载,或不该加载时强行拉取大图
-
href只能指向一个文件,比如banner-1200.jpg—— 它代表你预估用户最可能看到的那个尺寸版本
服务端推送下 as 属性错配导致静默失效
即使 HTTP/2 推送正常工作,as 值和实际资源 MIME 类型不匹配,仍会破坏缓存复用:浏览器不会报错,但请求头中的 Accept 与响应头 Content-Type 对不上,结果就是“推了也白推”,后续真实请求仍要重下。
验证方法很简单,打开 Network 面板 → 点击推送资源 → Headers 标签页,逐行比对:
- 字体推送:响应头
Content-Type: font/woff2,link中必须有as="font"+type="font/woff2" - CSS 推送:响应头
Content-Type: text/css,link中as必须是"style",不是"stylesheet" - JSON 数据推送:响应头
Content-Type: application/json,link中as应为"fetch"
prefetch 不能替代 preload 处理首屏字体或 CSS
有人试图用 rel="prefetch" 替代 rel="preload" 来“跨页面预热”字体,这是危险操作:prefetch 优先级为 Low,浏览器只在空闲时下载,而首屏字体加载延迟直接触发 FOIT/FOUT。
真正该用 prefetch 的场景很明确:
- 下一屏 HTML 页面(如
checkout.html) - 非首屏 JS 模块(如产品详情页的评论组件)
- 第三方 CDN 域名连接(配合
rel="preconnect")
字体、关键 CSS、首屏图片这些,只要还在当前页渲染链路上,就必须用 preload,哪怕服务端开了 HTTP/2 Push —— 因为 Push 的可靠性依赖路径静态性,而动态路径或条件样式往往推不到。



















