一直在与页面打交道, 却对浏览器渲染原理没有作个深入探索. 刚刚写完开源翻译项目, 立马整理资料, 记录下来

更新


[2019-3-23]

Added

  • 新增实际渲染过程
  • 新增CSS渲染机制

Changed

  • 更改CSS阻塞相关内容

[2019-3-28]

Added

  • 补充导致重排的因素
  • 补充导致重绘的因素

过程


构建解析DOM树

完整的过程

  • 浏览器读取通过TCP等其他方式传输的字节
  • 浏览器根据文件的编码方式, 将字节转化为字符
  • 浏览器将字符串转化为H5标准的令牌(尖括号的字符串)
  • 转化为对应的DOM节点并完善其属性
  • 根据节点的对应关系构建DOM树

构建解析CSSOM树

  • 浏览器根据文件的编码方式, 将字节转化为字符
  • 浏览器将字符串转化为H5标准的令牌
  • 转化为对应的CSS Rules样式对象
  • 根据样式对象的层级关系构建CSSOM树

构建Render Tree

遍历DOM TreeCSSOM Tree, 合并为渲染树(Render Tree).

  • 只构建可见节点
  • 构建完成之后发射节点

计算节点(布局)(flow)

计算节点的位置和大小等信息

  • 从渲染树的root节点进行遍历
  • 输出盒模型

绘制(paint)

将渲染树中的每个节点转换成屏幕上的实际像素

  • DOM Tree或者CSSOM Tree被修改, 只能重新执行上述步骤

阻塞渲染


CSS阻塞

防止DOM元素样式突然发生变化

  • 外部CSS会阻碍DOM渲染, 但是并不影响DOM解析构建(使用network测试), 避免重排和重绘
  • 外部CSS会阻塞JS执行, 避免JS获取不到最新的CSS样式

JS阻塞

防止出现js操作DOM、修改css的情况

  • 会阻塞CSS构建
  • 当解析器遇到一个script标记时, 会暂停构建DOM, 将控制权交给js引擎, 等待执行js之后, 从中断的地方回复DOM构建

补充


实际渲染过程

  • 为了用户体验, 会尽快将内容显示在屏幕上, 出现一边加载, 一边解析, 一边渲染的情况

CSS渲染机制

  • CSS采用逆向(从右至左)的渲染机制
  • 避免选择器层级过深
    • 比如div p span.text选择器, 浏览器会找到span.text这个元素, 然后依次检查它的父级是否包含pdiv元素

导致重排的因素

  • resize
  • DOM增减
  • DOM大小位置改变
  • 获取及时性较高的属性
    • getComputedStyle
    • offsetTop

导致重绘的因素

  • visibility
  • 自身外观变化