非关键脚本不加defer或async必然阻塞HTML解析,导致首屏白屏;因其强制暂停DOM构建,下载执行完才继续,即使仅埋点也会拖慢FCP。

非关键脚本不加 defer 或 async,首屏必然白屏——这不是 JS 执行慢,而是浏览器被它卡在解析阶段。
为什么 script 不加属性就等于阻塞首屏
浏览器解析 HTML 时,遇到 <script src="app.js"></script> 会立刻暂停 DOM 构建,同步下载、执行完才继续。哪怕这个脚本只做埋点,也会拖慢 FCP(首次内容绘制)。
- 现象:Network 面板里
app.js的 Initiator 显示为parser,且 FCP 前有明显空白 - 本质:不是脚本本身重,而是它打断了 HTML 解析流,DOM 树无法完成,浏览器连渲染准备都做不了
- 误区:以为“放
</body>前就安全”——确实能避免白屏,但依然阻塞 DOM 构建,且无法保证多个脚本的执行顺序
defer 和 async 到底该选哪个
二者都让下载不阻塞 HTML 解析,但执行时机和顺序完全不同,选错反而引入新问题。
-
defer:适合业务逻辑脚本(如 Vue 初始化、表单校验、API 请求封装)。下载并行,执行在 DOM 解析完成后、DOMContentLoaded之前,且严格按 HTML 中出现顺序执行 -
async:适合完全独立、无 DOM 依赖、不关心执行顺序的脚本,比如analytics.js、广告 SDK。下载完立刻执行,可能早于document.readyState === 'loading',必须自行加判断 - 绝对别混用:同一个页面里既有
defer又有async的脚本,且存在依赖关系(比如 A 初始化组件,B 埋点),结果不可控
哪些脚本算“非关键”,怎么识别
关键与否不看文件名,而看它是否参与首屏渲染或用户首次交互前的逻辑链。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- 非关键典型:统计脚本(
gtag.js、umami.js)、客服浮窗、分享按钮、离线缓存(sw.js注册除外)、A/B 测试 SDK - 看似非关键实则关键:某些 UI 组件库的按需加载入口(如
element-plus的auto-imports)、首屏弹窗的初始化逻辑 - 验证方式:Chrome DevTools → Coverage 面板刷新页面,看哪些 JS 文件在 FCP 前从未执行;或者临时注释掉某脚本,观察首屏是否仍可完整交互
兼容性与兜底陷阱
defer 在所有现代浏览器中支持良好(IE9+),但 async 在低版本 Android WebView 中可能行为异常;更隐蔽的问题是第三方脚本自带内联 document.write()。
- 老版本 Safari(≤12.1)和部分安卓 WebView 不支持
loading="lazy",但defer/async没这个问题 - 某些第三方脚本(尤其旧版统计工具)会动态插入
document.write(),一旦用了async,它可能在document尚未 ready 时执行,直接清空整个文档流 - 兜底方案不是“全用
defer”,而是对可疑脚本做沙箱化:<iframe sandbox="allow-scripts" src="third-party-loader.html"></iframe>,或用fetch+eval(慎用)控制加载节奏
真正容易被忽略的,是那些没写 src 却写了内联逻辑的 <script>console.log('init')</script>——它默认同步执行,一样阻塞解析,除非你确认它小到必须立刻跑,否则也得评估是否该抽离或延迟。


















