资源加载顺序由浏览器解析规则、阻塞关系和加载策略共同决定;同步脚本和样式表会阻塞渲染,async/defer可优化执行时机;Performance API能精准定位隐形阻塞者,FCP、DOMContentLoad时间及资源启动集中度是关键验证指标。

资源加载顺序不是“先写谁就先加载”,而是由浏览器解析规则、阻塞关系和加载策略共同决定的。真正拖慢首屏的,往往不是某个大文件,而是它前面一个被忽略的小脚本或样式表——卡住了整个关键渲染路径。
识别哪些资源在阻塞页面渲染
浏览器会按 HTML 顺序解析,但不同资源对渲染的影响差异很大:
- <script>(无属性):同步执行,遇到即暂停 HTML 解析,必须等 JS 下载、解析、执行完才继续
- <link rel="stylesheet">:不阻塞 HTML 解析,但会阻塞后续 <script> 执行(即使 script 在它后面),也会阻塞首次绘制(FCP)
- <script async>:下载时不阻塞解析,但下载完立即执行,可能打断 DOM 构建
- <script defer>:下载不阻塞,执行推迟到 DOM 解析完成、DOMContentLoaded 触发前,最安全的顺序控制方式
用 Performance API 看清真实加载时序
别只看 Network 面板的瀑布图——它显示的是网络请求时间,而实际渲染卡点常藏在解析与执行阶段。推荐组合使用:
- 调用
performance.getEntriesByType('navigation')查domContentLoadedEventStart和loadEventStart,确认 DOM 构建是否被延迟 - 调用
performance.getEntriesByType('resource')过滤出initiatorType === 'script'或initiatorType === 'link'的条目,按startTime排序,观察谁在关键节点前“堵着” - 重点关注
responseEnd到domContentLoadedEventStart之间的空档:如果有长间隙,说明是 JS 执行或 CSSOM 构建耗时,而非网络慢
定位“隐形阻塞者”:动态插入与跨域资源
很多性能问题来自非静态声明的资源,它们不会出现在原始 HTML 中,却实实在在影响加载节奏:
立即学习“前端免费学习笔记(深入)”;
- JS 动态创建的
document.createElement('script').src = '...':这类脚本 initiatorType 是other,需结合 URL 关键词(如includes('analytics'))识别 - 跨域
<link rel="stylesheet" href="https://cdn.example.com/style.css">:若未配置Timing-Allow-Origin响应头,Performance API 将缺失 DNS、连接等字段,表现为domainLookupStart === 0,此时不能判断是真快还是数据不可信 - 内联
<style>内容过大:虽不触发网络请求,但会拉长 HTML 解析时间,尤其当其中包含大量 @import 或复杂选择器时
验证优化效果的实操检查点
改完代码后,别只看“总加载时间降了”,要盯住三个具体信号:
- FCP(首次内容绘制)是否提前:说明首屏关键资源(HTML + 关键 CSS + 首屏 JS)已脱离阻塞链
- DOMContentLoad 时间是否接近 HTML 解析完成时间:若差值<50ms,说明没有长任务或同步脚本拖尾
- 是否存在连续多个 resource 条目 startTime 高度集中:比如 5 个脚本都在同一毫秒级启动,说明它们共享同一个阻塞源头(如一个前置同步 script)



















