DOM渲染原理

浏览器渲染过程

  • 解析HTML,构建DOM树(这里遇到外链,此时会发起请求)
  • 解析CSS,生成CSS规则树
  • 合并DOM树和CSS规则,生成render树
  • 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  • 绘制render树(paint),绘制页面像素信息
  • 浏览器会将各层的信息发送给GPU,GPU将各层合成(composite),显示在屏幕上

1. 构建DOM树

<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="style.css" rel="stylesheet">
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg"></div>
  </body>
</html>
复制代码

不管是DOM仍是CSSOM,都是要通过Bytes → characters → tokens → nodes → object model这个过程。css

image

DOM树构建过程:当前节点的全部子节点都构建好后才会去构建当前节点的下一个兄弟节点。html

2. 构建CSSOM树

上述也提到了CSSOM的构建过程,也是树的结构,在最终计算各个节点的样式时,浏览器都会先从该节点的广泛属性(好比body里设置的全局样式)开始,再去应用该节点的具体属性。还有要注意的是,每一个浏览器都有本身默认的样式表,所以不少时候这棵CSSOM树只是对这张默认样式表的部分替换。node

3. 生成render树

DOM树和CSSOM树合并生成render树web

image

简单描述这个过程:浏览器

DOM树从根节点开始遍历可见节点,这里之因此强调了“可见”,是由于若是遇到设置了相似display: none;的不可见节点,在render过程当中是会被跳过的(但visibility: hidden; opacity: 0这种仍旧占据空间的节点不会被跳过render),保存各个节点的样式信息及其他节点的从属关系。bash

4. Layout 布局

有了各个节点的样式信息和属性,但不知道各个节点的确切位置和大小,因此要经过布局将样式信息和属性转换为实际可视窗口的相对大小和位置。dom

5. Paint 绘制

万事俱备,最后只要将肯定好位置大小的各节点,经过GPU渲染到屏幕的实际像素。布局

Tips

  • 在上述渲染过程当中,前3点可能要屡次执行,好比js脚本去操做dom、更改css样式时,浏览器又要从新构建DOM、CSSOM树,从新render,从新layout、paint;
  • Layout在Paint以前,所以每次Layout从新布局(reflow 回流)后都要从新出发Paint渲染,这时又要去消耗GPU;
  • Paint不必定会触发Layout,好比改个颜色改个背景;(repaint 重绘)
  • 图片下载完也会从新出发Layout和Paint;

image

什么时候触发reflow和repaint

  • reflow(回流): 根据Render Tree布局(几何属性),意味着元素的内容、结构、位置或尺寸发生了变化,须要从新计算样式和渲染树;
  • repaint(重绘): 意味着元素发生的改变只影响了节点的一些样式(背景色,边框颜色,文字颜色等),只须要应用新样式绘制这个元素就能够了;
  • reflow回流的成本开销要高于repaint重绘,一个节点的回流每每回致使子节点以及同级节点的回流;