CSS重排Reflow和重绘Repaint

一、什么是重排(回流)Reflow和重绘Repaint

1.重排(回流)

重排(回流):当渲染 render 树中的一部分或者全部因为大小边距、布局等问题发生改变而需要 DOM 树重新计算的过程,每个页面至少需要一次重排,就是在页面第一次加载的时候。

2.重绘

当元素的一部分属性发生改变,如外观、背景、颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,使元素呈现新的外观叫做重绘。

3.页面渲染过程

浏览器加载,解析,渲染页面,分为五个步骤:

1. 浏览器将获取的 HTML 文档解析成 DOM 树;
2. 处理 CSS 标记,构成层叠样式表模型(CSSOM);
3. 将 DOM 和 CSSOM 合并为渲染树(render tree);
4. 渲染树的每个元素的内容都是计算过的,称之为 布局layout;
5. 将渲染树上的各个节点绘制到屏幕上,称之为 绘制painting;

浏览器下载完页面中的所有组件——HTML标记、JavaScript、CSS、图片之后会解析生成两个内部数据结构——DOM树和渲染 render 树
DOM树表示页面结构,渲染树表示DOM节点如何显示。DOM树中的每一个需要显示的节点在渲染树种至少存在一个对应的节点(隐藏的DOM元素 disply值为none 在渲染树中没有对应的节点)。渲染树中的节点被称为“帧”或“盒”,符合CSS模型的定义,理解页面元素为一个具有填充边距、边框和位置的盒子。一旦 DOM和渲染树构建完成,浏览器就开始显示(绘制)页面元素。
当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘

所以说,第四步(重新生成布局)+ 第五步(重新绘制)是最耗时的部分,这两步合起来,就是我们通常所说的渲染

网页生成的时候,至少会渲染一次

在用户访问的过程中,还会不断重新渲染

重新渲染需要重复之前的第四步(重排)+ 第五步(重绘)或者只有第五个步(重绘)。

也就是说,重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)

二、引起重排(回流)Reflow和重绘Repaint 的属性

1.引起重排的情况

很显然,每次重排,必然会导致重绘,那么,重排会在哪些情况下发生?

  1. 页面初始化的时候;

  2. 操作DOM时,如添加或者删除可见的DOM元素;

  3. 元素位置改变;

  4. 元素的尺寸改变——边距、填充、边框、宽度和高度;

  5. 元素内容改变;(例如:一个文本被另一个不同尺寸的图片替代,用户在input框中输入文字)

  6. 浏览器窗口尺寸改变——resize事件发生时;

  7. 计算 offsetWidth 和 offsetHeight 属性;

  8. 设置 style 属性;

  9. 改变文字大小;

  10. 添加/删除样式表;

  11. 激活伪类,如:hover;

  12. 操作class属性;

这些都是显而易见的,或许你已经有过这样的体会,不间断地改变浏览器窗口大小,导致UI反应迟钝(某些低版本IE下甚至直接挂掉),现在你可能恍然大悟,没错,正是一次次的重排重绘导致的!

常见引起重排属性和方法
widthheightpaddingmargin
displayborder-widthbordertop
positionfont-sizefloattext-align
overflowfont-weighttopleft
font-familyline-heightvertical-alignright
clearwhite-spacebottommin-height
offsetTopoffsetLeftoffsetWidthoffsetHeight
scrollTopscrollLeftscrollWidthscrollHeight
clientTopclientLeftclientWidthclientHeight
getComputedStyle()(currentStyle in IE)
getBoundingClientRect()
scrollIntoViewIfNeeded()

重排影响的范围:

触发重排时会对周围DOM重新排列,影响的范围有两种:

  • 全局范围:从根节点html开始对整个渲染树进行重新布局。
  • 局部范围:对渲染树的某部分或某一个渲染对象进行重新布局

2.引起重绘的情况

常见的重绘元素
colorborder-stylevisibilitybackground
text-decorationbackground-imagebackground-positionbackground-repeat
outline-coloroutlineoutline-styleborder-radius
outline-widthbox-shadowbackground-size

3.如何减少重排(Reflow)和重绘(Repaint)

重排和重绘是DOM编程中耗能的主要原因之一。

CSS中避免重排、重绘
  1. 避免设置多层内联样式;
  2. 尽可能在DOM树的最末端改变class;
  3. 动画效果应用到position属性为absolute或fixed的元素上;
  4. 避免使用table布局,table属性变化使用会直接导致布局重排或者重绘;(table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。这也是为什么我们要避免使用table做布局的一个原因。)
  5. 不要在布局信息改变的时候做查询(会导致渲染队列强制刷新);
  6. 用translate替代top改变;
  7. 用opacity替代visibility(在独立图层下优化重绘)多用visibility:hidden少用display:none;
  8. 使用css3硬件加速,可以让transform、opacity、filters等动画效果不会引起回流重绘。
JS操作避免重排、重绘
  1. 减少直接操作dom元素,不要一条一条地修改 DOM 的样式,改用className用于控制;
  2. 不要把 DOM 结点的offsetLeft等属性值放在一个循环里当成循环里的变量;
  3. 如果需要创建多个DOM节点,可以使用DocumentFragment创建一个子树,之后一次性的拷贝到document;
  4. 先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘;
  5. 对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天弈初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值