1

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 前言
三 浏览器渲染过程
四 重绘
五 回流
六 优化
七 参考文献

二 前言

返回目录
  1. 什么是回流?
  2. 什么情况下触发回流?
  3. 什么是重绘?
  4. 什么情况下触发重绘?
  5. 如何避免回流和重绘?

三 浏览器渲染过程

返回目录

如上图,浏览器的渲染过程为:

  1. 解析 HTML,生成 DOM
  2. 解析 CSS,生成 CSS 规则树(CSS Rule Tree)
  3. DOM TreeCSS Rule Tree 相结合,生成 渲染树Render Tree
  4. 从根节点开始,计算每一个元素的大小、位置,给出每个节点所应该出现的屏幕精确坐标,从而得到基于渲染树的 布局渲染树Layout of the render tree)。
  5. 遍历渲染树,将每个节点用 UI 渲染引擎来绘制,从而将整棵树绘制到页面上,这个步骤叫 绘制渲染树Painting the render tree

这个过程面试中非常常见,小伙伴们稍微记一下,后面章节会反复提及。

四 重绘

返回目录
  • 什么是重绘?

重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少

在浏览器渲染过程中,对应步骤 5,即每次发生重绘,我们都会重新绘制渲染树,然后进行展示。

  • 如何触发重绘?
  1. 修改背景色、颜色(backgroundcolor
  2. 设置可见度(visibility
  3. 设置背景图(background-image
  4. ……等

五 回流

返回目录
  • 什么是回流?

回流(reflow):又叫重排(layout)。当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。

此时,浏览器需要重新经过计算,计算后还需要重新页面布局,然后进行绘制渲染,因此是较重的操作。

  • 如何触发回流?
  1. 添加删除 DOM 元素
  2. 改变边框、边距、宽高(bordermarginpaddingwidthheight
  3. 浏览器改变窗口(resize
  4. ……等

六 优化

返回目录

这时候需要一句总结:

  • 回流必定会发生重绘,重绘不一定会引发回流。

看图理解:回流动了 Layout,触发了 Render Tree 进行重新渲染,所以后面还会 Painting。而重绘后面直接 Display,不会触发回流。

当然,很多浏览器都会优化操作:

浏览器会维护 1 个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会处理队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。

那么,我们做一道题:

输出下面回流和重绘的次数:

var s = document.body.style;
s.padding = "2px";
s.border = "1px solid red";
s.color = "blue";
s.backgroundColor = "#ccc";
s.fontSize = "14px";

document.body.appendChild(document.createTextNode('abc!'));

答案:触发回流 4 次,触发重绘 6 次。


在这里,我们需要了解的是:

  • JS 是单线程的,JS 解析的时候渲染引擎是停止工作的

所以,结合这些内容,我们可以根据此大概说一下:

  • 如何减少回流和重绘?
  1. 【CSS】使用 visibility 替换 display
  2. 【CSS】避免 table 布局。对于 Render Tree 的计算通常只需要遍历一次就可以完成,但是 table 布局需要计算多次,通常要花 3 倍于等同元素的时间,因此要避免。
  3. 【JS】避免频繁做 widthheight 等会触发回流的操作。
  4. 【JS】操作 DOM 的时候,如果是添加 DOM 节点,可以将所有节点都在 JS 中操作完毕,再进行渲染(一次性)

七 参考文献

返回目录

jsliang 的文档库由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。<br/>基于 https://github.com/LiangJunrong/document-library 上的作品创作。<br/>本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。

jsliang
393 声望31 粉丝

一个充满探索欲,喜欢折腾,乐于扩展自己知识面的终身学习斜杠程序员