9. 浏览器渲染与 V8 协作
中要先明确边界:V8 执行 JS,但不负责渲染页面。页面渲染属于 Blink、合成器、GPU 等模块。
从页面到像素
常见渲染链路:
- 解析 HTML,构建 DOM。
- 解析 CSS,计算样式。
- Layout,计算元素位置和尺寸。
- Paint,生成绘制指令。
- Composite / Raster,合成和光栅化。
- 显示到屏幕。
记忆顺序:DOM → Style → Layout → Paint → Composite → Display。
V8 插入在哪里
遇到脚本时,Blink 会调用 V8 编译和执行 JS。JS 执行可能影响后续渲染:
- 修改 DOM,会影响 DOM 树。
- 修改 class / style,会影响样式计算。
- 读取
offsetWidth、getBoundingClientRect等几何信息,可能触发布局刷新。
script、defer、async
- 同步脚本:阻塞 HTML 解析,执行完再继续。
defer:下载不阻塞解析,解析完成后按顺序执行。async:下载不阻塞解析,下载完成后尽快执行,顺序不保证。type="module":默认接近defer。
强制同步布局
如果 JS 先修改样式,再立刻读取布局信息,浏览器可能被迫马上完成样式和布局计算,这叫 forced synchronous layout。
它会打断浏览器批量处理节奏,是前端性能优化里的高频问题。
rAF 与微任务
Promise.then 属于微任务,通常在当前 JS 调用栈结束后执行。requestAnimationFrame 和浏览器渲染帧相关,更适合做视觉更新。
不要把微任务理解成“下一帧”,它通常会在渲染前被清空。
总结
V8 负责 JS 执行,Blink 负责 DOM/CSS 和渲染管线。JS 通过修改 DOM、样式和读取布局信息影响渲染,性能问题常出在主线程长任务和强制同步布局。