blocking="render"不是标准属性,浏览器会忽略它;真正控制脚本阻塞行为的只有defer、async和默认同步执行。

blocking="render" 不是标准属性,浏览器会忽略它
HTML 规范中根本不存在 blocking="render" 这个属性。你在 <script> 标签里写上它,浏览器既不会报错,也不会按你预期去“阻塞渲染”——它只是被当作一个无意义的自定义属性直接丢弃。
真正能控制脚本是否阻塞 HTML 解析和页面渲染的,只有原生属性:defer、async 和默认的同步执行行为。
- 没加任何属性的
<script src="..."></script>:**同步加载+执行**,会阻塞 HTML 解析和后续渲染(即“阻塞 render”) -
defer:下载不阻塞解析,执行在 DOM 构建完成后、DOMContentLoaded前,且按顺序执行 -
async:下载不阻塞解析,下载完立即执行(可能乱序),不保证执行时机
为什么有人误用 blocking="render"?
这个写法常见于对 loading="lazy" 或 React/Vue 的 suspense 边界逻辑的混淆,也可能是把构建工具(如 Webpack)的 chunk 配置项(如 webpackChunkName)或某些 SSR 框架的注释语法(如 <!--# script -->)记混了。
更现实的情况是:开发者看到页面白屏时间长,想“强制让某个脚本晚点执行”,但没查 MDN 就随手写了看似合理的属性名。
- Chrome、Firefox、Safari 都不识别
blocking属性,DevTools Elements 面板里能看到它,但 Network 或 Performance 面板里完全不影响资源加载时序 - 如果你依赖它做“非阻塞初始化”,实际效果等于没加限制——脚本照常同步阻塞
- Lighthouse 或其他性能扫描工具也不会警告该属性无效,容易埋下长期隐患
想真正避免脚本阻塞渲染,该怎么做?
核心思路就两条:要么移出关键路径,要么移交控制权给浏览器。别试图用不存在的属性“打补丁”。
- 首屏不需要的 JS(如统计、分享按钮、非关键交互):用
async加载,或用load事件后动态document.createElement('script')插入 - 需要 DOM 就绪但又不想阻塞解析的初始化逻辑:改用
defer,或包裹进DOMContentLoaded监听器 - 内联脚本(
<script>...</script>)无法加defer/async,必须精简并确保无副作用;否则建议外链 +defer - 现代方案:用
import('./module.js')动态导入,配合await控制执行时机,比属性更灵活
检查你是否真的被阻塞了?
别靠猜。打开 Chrome DevTools → Performance 面板 → 录制一次页面加载,重点关注 “Main” 线程上的 Parse HTML 和 Function Call(对应脚本执行)是否长时间连续占用,中间有没有空白间隙。
如果发现某段脚本执行卡住了解析,而你又没加 defer 或 async,那问题就定位到了——不是属性写错了,是根本没用对机制。
真正难处理的是那些隐式阻塞:比如一个第三方 SDK 内部同步加载另一个脚本、或通过 document.write 强行插入内容。这种没法靠属性解决,得换加载方式或找替代方案。

















