17 — HTML / CSS / JavaScript 处理管线
先澄清一个高频误区:HTML 和 CSS 通常说解析,不说编译成机器码;JavaScript 才会进入 V8 的编译和 JIT 优化管线。
总体分工
- HTML:Blink 解析,生成 DOM。
- CSS:Blink 解析样式表,计算每个元素的样式。
- JavaScript:V8 解析、生成字节码、解释执行,并对热点代码 JIT 优化。
- Web API:JS 通过 bindings 调用 Blink 或其他 Chromium 服务的 C++ 实现。
HTML 怎么处理
HTML 是流式、增量解析:
- 网络字节解码成文本。
- Tokenizer 把文本切成 token。
- Tree Builder 根据 HTML 规则构建 DOM。
- 遇到同步脚本时,解析可能暂停,先下载并执行脚本。
- 预加载扫描器可以提前发现图片、脚本、样式等资源。
结论:HTML 的产物是 DOM,不是可执行机器码。
CSS 怎么处理
CSS 被解析成样式规则,再和 DOM 结合:
- 解析
<link>、<style>、行内样式。 - 选择器匹配 DOM 节点。
- 按级联、继承、优先级计算 computed style。
- 样式变化时尽量只让受影响部分失效和重算。
结论:CSS 不是先完整“编译”成另一个程序,而是参与样式计算、布局和绘制。
JS 怎么处理
JS 由 V8 负责:
- 解析源码。
- 生成字节码并由 Ignition 执行。
- 收集类型和对象形状反馈。
- 热点代码进入 Sparkplug / Maglev / Turbofan 等优化层。
- 优化假设失败时 deopt 回退。
结论:JS 的“编译”是运行时发生的,并且是反馈驱动、可回退的。
DOM、CSSOM、渲染树怎么理解
教程里常说“DOM + CSSOM 生成渲染树”。中更稳的说法是:
- DOM 表示文档结构。
- CSSOM / 样式规则表示样式来源。
- 浏览器把样式计算到元素上,再生成布局和绘制所需的数据结构。
不必强行寻找一个叫“渲染树”的固定对象,理解数据依赖关系即可。
script、defer、async
- 同步脚本会阻塞 HTML 解析。
defer下载不阻塞解析,解析完成后按顺序执行。async下载不阻塞解析,下载完成后尽快执行,顺序不保证。- 模块脚本默认接近
defer。
总结
HTML 解析成 DOM,CSS 解析并计算样式,JS 由 V8 执行和优化。三者最终汇入 style、layout、paint、composite 管线;JS 可以通过 DOM 和样式修改触发后续渲染更新。