如何让图片作为render-blocking资源优先加载阻塞后续渲染
渲染阻塞模式加载首图的实现方法
标准HTML规则下,带src属性的普通
<img>属于非渲染阻塞资源:浏览器解析到img标签时会发起资源请求,但不会暂停DOM解析和后续页面渲染流程,这就是你观察到的默认异步加载表现。
要实现图片加载完成后再执行后续页面渲染,按可靠性排序可选择以下方案:
方案1:高优先级预加载+轻量阻塞逻辑(推荐,兼容性覆盖95%以上现代浏览器)
这个方案会把目标图片的请求优先级提到最高,确保它是页面第一个加载的资源,同时在资源就绪前拦截页面渲染:
- 在
<head>标签的最顶部(所有其他meta、样式、脚本之前)添加预加载声明,强制浏览器优先发起该图片的请求:
<head> <!-- 替换href为你的图片实际地址,和后续img标签的src保持完全一致 --> <link rel="preload" as="image" href="your-hero-image.jpg" fetchpriority="high">
- 紧接在预加载标签后添加内联阻塞脚本,在图片加载完成前隐藏未就绪的页面内容:
<script> const targetImg = new Image(); targetImg.src = "your-hero-image.jpg"; // 图片未加载完成时插入全屏遮罩,拦截后续内容渲染 if (!targetImg.complete) { const renderMask = document.createElement('div'); renderMask.style.cssText = 'position:fixed;inset:0;background:#fff;z-index:2147483647;border:none'; document.documentElement.appendChild(renderMask); // 无论图片加载成功还是失败,都移除遮罩放行渲染,避免页面卡死 targetImg.onload = targetImg.onerror = () => renderMask.remove(); } </script> <!-- 原页面所有其他内容(meta、样式、脚本、body内的img标签和其他结构)放在这之后 -->
方案2:同步请求阻塞(不推荐,仅兼容极老旧浏览器场景)
如果需要兼容不支持preload的老旧浏览器,可以用同步XHR请求强制阻塞解析,但注意同步请求会阻塞主线程,用户体验较差:
<head> <script> const req = new XMLHttpRequest(); req.open('GET', 'your-hero-image.jpg', false); // false参数代表同步请求,会阻塞后续解析 req.send(); // 请求完成后才会执行到后续逻辑 </script> </head>
关键注意事项
- 预加载的图片地址必须和页面中实际img标签的src完全一致,否则会触发重复请求,浪费带宽
- 阻塞逻辑仅能用于首屏核心必现的图片,滥用会直接拉长首屏加载时间,影响页面性能评分
- 必须配置
onerror兜底逻辑,避免图片加载失败时页面被永久遮罩 - 不要尝试把img标签直接写在
<head>里实现阻塞,这不符合HTML规范,浏览器会自动把这类非法标签移动到body中,达不到阻塞效果
内容的提问来源于stack exchange,提问作者haveman
相关产品推荐
相关产品推荐

