重绘及回流

虚空假面
• 阅读 1007

浏览器的渲染过程

  1. 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  3. Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  4. Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  5. Display:将像素发送给GPU,展示在页面上。

为了构建渲染树,浏览器主要完成了以下工作:

  1. 从DOM树的根节点开始遍历每个可见节点。
  2. 对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们。
  3. 根据每个可见节点以及其对应的样式,组合生成渲染树。

第一步中,既然说到了要遍历可见的节点,那么我们得先知道,什么节点是不可见的。不可见的节点包括:

  1. 一些不会渲染输出的节点,比如script、meta、link等。
  2. 一些通过css进行隐藏的节点。比如display:none。注意,利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上。

回流

前面我们通过构造渲染树,我们将可见DOM节点以及它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流。

重绘

最终,我们通过构造渲染树和回流阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(位置、大小),那么我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点。

何时发生回流

回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况:

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

浏览器的优化机制

现代的浏览器都是很聪明的,由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:

  1. offsetTop、offsetLeft、offsetWidth、offsetHeight
  2. scrollTop、scrollLeft、scrollWidth、scrollHeight
  3. clientTop、clientLeft、clientWidth、clientHeight
  4. getComputedStyle()
  5. getBoundingClientRect

减少重绘与回流

CSS

  1. 使用 transform 替代 top
  2. 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局
  3. 避免使用table布局,可能很小的一个小改动会造成整个 table 的重新布局。
  4. 尽可能在DOM树的最末端改变class,回流是不可避免的,但可以减少其影响。尽可能在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。
  5. 避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多。
  6. 将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择 requestAnimationFrame,详见探讨 requestAnimationFrame。
  7. 避免使用CSS表达式,可能会引发回流。
  8. 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe等标签,浏览器会自动将该节点变为图层。
  9. CSS3 硬件加速(GPU加速),使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。

    JavaScript

  10. 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
  11. 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
  12. 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
  13. 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
PTA 是否同一棵二叉搜索树(25 分)
是否同一棵二叉搜索树(25 分)给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2,1,3}和{2,3,1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。输入格式:输入包含若干组测
秃头王路飞 秃头王路飞
3年前
浏览器工作原理
浏览器渲染过程浏览器渲染1.解析HTML文件,构建DOM树,同时浏览器主进程负责下载CSS文件2.CSS文件下载完成,解析CSS文件成树形的数据结构,然后结合DOM树合并成RenderObject树3.布局RenderObject树(Layout/reflow),负责RenderObject树中的元素的尺寸,位置等计算4.绘制RenderObject树(paint),绘制页面的像素信息5.浏览器主进程将默认的图层和复合图层交给GPU进程,GPU进
分布式id如何生成
1.UUID生成通过网卡、时间、随机数来保证生成的唯一的字符串。优点:(1)本地生成,生成简单(2)速度快(3)高可用;缺点:(1)无序,如果存入mysq,影响B的操作性能,因为B树是需要排序的;(2)占用空间较大(36个
浩浩 浩浩
4年前
【Flutter实战】布局类组件简介
4.1布局类组件简介布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排版(layout)方式不同。我们在前面说过Element树才是最终的绘制树,Element树是通过Widget树来创建的(通过Widget.createElement()),Widget其实就是Element的配置数据。在Flutter中,根据Widget是否
Stella981 Stella981
3年前
React的虚拟DOM
上一篇文章中,DOM树的信息可以用JavaScript对象来表示,反过来,可以根据这个用JavaScript对象表示的树结构来真正构建一颗DOM树。用JavaScript对象表示DOM信息和结构,当状态变更的时候,重新渲染这个JavaScript的对象结构,当然这样做,其实并没有更新到真正的页面上。但是可以用新渲染的对象树和旧的树进行对比,记录这两棵树
Stella981 Stella981
3年前
B+树原理以及Java代码实现
最初查找二叉树,由于树的高度会随着有序序列输入而急剧增长,后来出现平衡二叉树,红黑树。B树可以海量数据的快速查询检索,B树主要分为B树(B树),B树,B\树等。B树(B树)M路搜索树,参数M定义节点的分支个数;对于根节点孩子数目为\2,M\,对于其余节点孩子数目为\M/2,M\;每个节点含有关键字属性,至少M/21
Stella981 Stella981
3年前
Codeforces 1005F Berland and the Shortest Paths 【最短路树】【性质】
其实是一道裸题,如果没学过最短路树的话会比较难做,要想很久想到关键性质才能做出来。最短路树顾名思义,就是从一个图中生成出来一棵树,使得每个顶点到root的距离是单源最短路。如果有这样的树的话,那可见这样的树是符合题意的。怎么生成这样的树呢?关键在于记录前驱father,一个距离root最短路是6的点必定从一个距离root最短路是5的点到达(这两个点之
Stella981 Stella981
3年前
H5游戏性能优化整理(cocos
近期在一家公司负责H5游戏加载速度优化,这里把近期做的项目优化项做一个整理分享:(若文中有错误的地方,还请指出。)   分享流程:了解html渲染流程html相关优化http相关优化项目结构和游戏流程及优化游戏渲染相关优化代码编写优化html渲染流程HTML解析过程:构建DOM树、构
Wesley13 Wesley13
3年前
JZ18 二叉树镜像
JZ18二叉树镜像题目操作给定的二叉树,将其变换为源二叉树的镜像。思路先遍历,节点入栈,再依次出栈调换左右节点遍历的过程中调换左右节点代码coding:utf8classTreeNode:def__init__
混世魔王 混世魔王
2年前
皕杰报表查询表单中的下拉树控件
所谓下拉树控件就是在单元格里生成一个下拉树。下面我们就看看下拉树如何设计?在皕杰报表查询表单中选择单元格控件为下拉树,就可以为下拉树设置属性和数据。属性包括多选模式、支持多选模式、只能选叶子节点、默认展开到第几层。数据包括数据来源和节点数据。设置界面见下图
深入理解左倾红黑树 | 京东物流技术团队
平衡二叉搜索树平衡二叉搜索树(BalancedBinarySearchTree)的每个节点的左右子树高度差不超过1,它可以在O(logn)时间复杂度内完成插入、查找和删除操作,最早被提出的自平衡二叉搜索树是AVL树。AVL树在执行插入或删除操作后,会根据节