美文网首页
回流和重绘

回流和重绘

作者: 神楽花菜 | 来源:发表于2020-04-08 17:09 被阅读0次

浏览器渲染过程


从上面这个图上,我们可以看到,浏览器渲染过程如下:

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM树
    将DOM树和CSSOM树结合,生成渲染树(Render Tree)
    Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)以确定对象位置, 浏览器根据各种样式来计算结果放在它该出现的位置.
  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将像素发送给GPU,展示在页面上。(这一步其实还有很多内容,比如会在GPU将多个合成层合并为同一个层,并展示在页面中。而css3硬件加速的原理则是新建合成层.)

渲染过程看起来很简单,让我们来具体了解下每一步具体做了什么。

渲染树构建

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

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

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

  • 一些不会渲染输出的节点,比如script、meta、link等。
    -一些通过css进行隐藏的节点。比如display:none。

注意,利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上。

从上面的例子来讲,我们可以看到span标签的样式有一个display:none,因此,它最终并没有在渲染树上。
注意:渲染树只包含可见的节点

回流

回流(reflow)就是布局引擎为frame 计算图形的过程。
前面我们通过构造渲染树,我们将可见DOM节点以及它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流。
.但是这里需要我们注意的是, 回流并不仅仅只是在渲染页面的时候会触发, 实际上当我们动态修改某个 css 属性或者操作 DOM 时, 都有可能会触发回流和重绘。
为了弄清每个对象在网站上的确切大小和位置,浏览器从渲染树的根节点开始遍历,我们可以以下面这个实例来表示:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

我们可以看到,第一个div将节点的显示尺寸设置为视口宽度的50%,第二个div将其尺寸设置为父节点的50%。而在回流这个阶段,我们就需要根据视口具体的宽度,将其转为实际的像素值。

重绘

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

何时发生回流重绘

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

添加或删除可见的DOM元素

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

YaHoo!性能小组总结了一些导致回流发生的一些因素:

  • 调整窗口大小
  • 改变字体
  • 增加或者移除样式表
  • 内容变化,比如用户在 input 框中输入文字, CSS3 动画等
  • 激活 CSS 伪类,比如 :hover
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidth和offsetHeight属性
  • 设置 style 属性的值

而重绘则是视觉效果变化引起的重新绘制。比如 color 或者 background 发生了变化,

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

优化建议

  1. 如果想设定元素的样式,通过改变元素的 class 类名 (尽可能在 DOM 树的最里层)
  2. 避免设置多项内联样式
  3. 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值(如前文示例所提)
  4. 权衡平滑和速度
  5. 避免使用 table 布局
  6. 避免使用 CSS 的 JavaScript 表达式 (仅 IE 浏览器)
    7.尽量避免使用transition:top,margin等,而是使用transform:translateY().

使用transform:translateX()时,浏览器会将其脱离文档流形成单独的层,并将其交给显卡进行管理.(使用css硬件加速)

当然,任何美好的东西都是会有对应的代价的,过犹不及。css3硬件加速还是有坑的:

  • 如果你为太多元素使用css3硬件加速,会导致内存占用较大,会有性能问题。
  • 在GPU渲染字体会导致抗锯齿无效。这是因为GPU和CPU的算法不同。因此如果你不在动画结束的时候关闭硬件加速,会产生字体模糊。
  • 由于形成了单独的层,在过渡时透明度会失效.

参考资料:
【开发必看】你真的了解回流和重绘吗?
你可能不了解的回流与重绘

相关文章

  • 面经 之 Browser浏览器读后感

    浏览器,原文请移步Browser | InterviewMap 回流和重绘 回流和重绘 - 掘金 存储 cooki...

  • 前端总结(后续继续更新)

    1,reflow和repaint:回流和重绘。回流:renderTree 重建。重绘:外观样式风格进行更新。(co...

  • 前端一些细节

    1,reflow和repaint:回流和重绘。回流:renderTree 重建。重绘:外观样式风格进行更新。(co...

  • 22,重绘、回流

    1,浏览器渲染机制 2,重绘 3,回流 > 重绘。 4,浏览器优化 5,减少重绘和回流

  • 浏览器渲染回流重绘与性能优化

    我们根据渲染的流程可知, 回流一定会触发重绘,而重绘不一定会回流。 渲染性能优化 回流和重绘的代价是比较昂贵的,渲...

  • DOM树 CSS树 render树 以及JS的加载

    回流和重绘回流一定会引起重绘而重绘可以单独触发 例如修改背景颜色 字体颜色等...引起回流的因素:1.DOM节点 ...

  • 前端性能优化(HTML、CSS、JS)

    1.HTML优化篇 1.减少重绘和回流 不了解重绘和回流请点击我要了解 回流这一阶段主要是计算节点的位置和几何信息...

  • 怎样区分页面的回流和重绘

    一、什么是回流和重绘 引起DOM树结构变化,页面布局变化的行为叫回流,且回流一定伴随重绘。只是样式的变化,不会引起...

  • 回流与重绘

    回流一定会触发重绘回流: DOM结构的增删改重绘: 颜色,背景, 字体等视觉上页面的改变 重绘不一定触发回流 如何...

  • 回流和重绘

    一、定义 (1)回流:当reader tree中的部分或全部节点的规模尺寸,布局,隐藏等改变而需要重建。这个过程称...

网友评论

      本文标题:回流和重绘

      本文链接:https://www.haomeiwen.com/subject/ewztmhtx.html