浏览器渲染原理

49 阅读2分钟

步骤如下

  1. 根据HTML构建HTML树(DOM树)

  2. 根据CSS构建CSS树(CSSOM树)

  3. 将两棵树合并成一颗渲染树(render tree)

  4. Layout(回流)布局(文档流、盒模型、计算大小和位置)

  5. Painting(重绘)绘制(将边框颜色、文字颜色、阴影等画出来)

  6. Compose合成(根据层叠关系展示画面)

有以下三种渲染方式

image.png

eg. div.remove()会触发当前消失,其他元素relayout

改变背景颜色,直接repaint+composite

改变transfrom,只需composite

具体可在[ csstriggers.com/ ]查看

何时发生回流重绘

当页面布局和几何信息发生变化的时候,就需要回流。

比如以下情况发生回流:

根据改变的范围和程度,渲染树中或大或小的部分需要重新计算,有些改变会触发整个页面的重排,比如,滚动条出现的时候或者修改了根节点。

  • 页面一开始渲染的时候(这肯定避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
  • 元素字体大小变化
  • 激活CSS伪类(例如::hover)

一些常用且会导致回流的属性和方法:

clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
scrollIntoView()、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()

以下情况发生重绘而不回流

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程重绘而不回流。

注意:回流一定会触发重绘,而重绘不一定会回流

减少回流和重绘

  • 使用 transform 替代 top
  • 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)
  • 不要把节点的属性值放在一个循环里当成循环里的变量。
  • 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
  • 动画实现的速度的选择,动画速度越快,回流次数越多,可以使用 requestAnimationFrame
  • CSS 选择符从右往左匹配查找,避免节点层级过多
  • 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于 video 标签来说,浏览器会自动将该节点变为图层。

动画优化

image.png