深入探讨浏览器渲染原理 repaint 和 reflow

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Candy_yl/article/details/79504179

浏览器渲染原理

浏览器解析大概的工作流程大致可归纳为四个步骤:
1. 解析HTML以构建DOM树:渲染引擎开始解析HTML文档,转换树中的html标签或js生成的标签到DOM节点,它被称为 – 内容树。
2. 构建渲染树:解析CSS(包括外部CSS文件和样式元素以及js生成的样式)成样式结构体,根据CSS选择器计算出节点的样式,创建另一个树 —- 渲染树(render tree)。
3. 布局渲染树: 从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
4. 绘制渲染树: 遍历渲染树,每个节点将使用UI后端层来绘制。

重绘与回流

当第一次打开一个页面时,至少会有一次重绘和回流。之后,如果渲染树发生了变动,那么可能会触发重绘或回流中的一个或二者。

如果渲染树的结点发生了结构性变化,例如宽度、高度或者位置上的变化时,那么会触发Reflow(回流)的逻辑。我们第一次进入一个页面时便会至少触发一次这个逻辑。
如果渲染树结点发生了非结构性变化,例如背景色等的变化时,那么会触发Repaint(重绘)的逻辑。

触发reflow和repaint

我们具体看看哪些操作会导致重绘或回流:

  • 增加、删除、修改DOM结点
  • 使用display:none;的方式隐藏一个结点会导致repaint与reflow,使用visibility:hidden;进行dom隐藏仅仅导致repaint(没有结构性变化,仅仅看不见而已)
  • 移动dom或着该dom进行动画
  • 添加新的样式,或者修改某个样式
  • 用户的一些操作诸如改变浏览器窗口大小,调整字体大小,滚动等等

如何减少回流和重绘

Reflow是不可避免的,只能将Reflow对性能的影响减到最小,给出下面几条建议:

1, 不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className,即将多次改变样式属性的操作合并成一次操作:
2,让要操作的元素进行”离线处理”,处理完后一起更新
- 使用DocumentFragment进行缓存操作,引发一次回流和重绘;
- 使用display:none技术,只引发两次回流和重绘;
3,不要用tables布局的一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
4,css里不要有表达式expression
5,尽量不要过多的频繁的去增加,修改,删除元素,因为这可能会频繁的导致页面reflow,可以先把该dom节点抽离到内存中进行复杂的操作然后再display到页面上。
6,请求如下值offsetTop, offsetLeft, offsetWidth, offsetHeight,scrollTop/Left/Width/Height,clientTop/Left/Width/Height,浏览器会发生reflow,建议将他们合并到一起操作,可以减少回流的次数。

猜你喜欢

转载自blog.csdn.net/Candy_yl/article/details/79504179