html依赖树必须由js主动采集建模,因dom顺序不等于执行顺序,需遍历dom按语义提取script/link等节点构建有向边,并结合initiator为parser的运行时数据校准,过滤preload、async脚本及非关键media资源,起点为document、终点为domcontentloaded。

HTML 依赖树不是靠看 <script></script> 标签顺序就能画出来的——浏览器实际加载和执行顺序,和 DOM 里写的顺序经常不一致。必须结合运行时采集 + 静态分析,才能得到真实可用的依赖结构。
怎么从 HTML 中提取真实资源依赖边
浏览器不会把 src、href、data-src 自动连成图。你得自己遍历 DOM,按语义分类提取:
-
<script src="a.js"></script>和<script type="module" src="b.mjs"></script>是显式同步/模块依赖,但type="module"不保证执行顺序,需额外解析import语句补全边 -
<link rel="stylesheet" href="main.css">是渲染阻塞依赖;rel="preload"只是下载提示,不构成关键路径边 - 自定义属性如
data-module="auth"或data-chunk="vendor"必须显式配置规则提取,否则会被html-loader或分析脚本忽略 -
srcset要单独处理:同一<img>可能对应多个物理资源,但关键路径只取当前设备匹配的那一项(用currentSrc读)
为什么不能直接用 DOM 树当依赖图
DOM 节点顺序 ≠ 执行顺序。几个典型反例:
-
<script async src="lib.js"></script>插入位置靠前,但可能晚于后面某个defer脚本执行 -
<link rel="stylesheet">后面跟着<script></script>,实际会阻塞该<script></script>,但 DOM 树里它们是兄弟节点,无父子/先后边关系 - 内联
<script>console.log(1)</script>会立即执行,但它在图中应作为“叶子节点”而非“无依赖节点”——它依赖前面所有阻塞资源完成
如何用 Chrome DevTools 抓出真实 CRP 依赖链
CRP 不是靠 Coverage 面板猜出来的,得看 Network 面板里的 Initiator 和 Priority:
- 打开 DevTools → Network → 刷新页面 → 点击任意资源,在 Headers 里找
Initiator字段:parser表示它是 HTML 解析中途触发的,属于关键阻塞点 - 多个
parser请求串在一起(比如A.css → B.css → app.js),说明存在隐式依赖链,B.css必须等A.css的 CSSOM 构建完才开始下载 - 再配合
Priority列:Highest才算真关键;High或Medium很可能已被挤出首屏路径 -
preload不参与依赖链构建,不可作为节点加入拓扑图
依赖图里哪些节点该保留、哪些该过滤掉
真正关键路径图的起点是 document,终点是 DOMContentLoaded,中间边由资源加载完成事件(load)、解析完成(readystatechange)、以及 CSSOM 构建完成共同决定。实操中要过滤掉这些干扰项:
-
async脚本虽不阻塞解析,但加载完成就执行,可能早于关键 CSS 解析完毕,导致样式未生效就操作 DOM —— 这类节点不应纳入关键路径边,但需记录其潜在冲突 -
media="print"的 CSS 不是关键资源,但若漏写media或写成media="(min-width: 0)",浏览器仍会同步加载并阻塞 —— 这类误配必须在提取阶段通过属性校验剔除 -
modulepreload能自动展开静态import链,但对动态路径(如import('./chunk-' + id + '.mjs'))完全失效,这类节点无法被建模为边,只能标记为“运行时未知依赖”
最易被忽略的是:依赖图不是静态快照,而是带时间戳的有向事件流。同一个 <script></script> 在不同设备或网络条件下,可能因 currentSrc 或 media 匹配结果不同,进入完全不同的依赖分支。建模时必须保留上下文维度,不能只存一个扁平化 ID 列表。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











