ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

reflow(重排/回流)、repaint(重绘)及其优化

2019-06-21 17:56:13  阅读:246  来源: 互联网

标签:触发 repaint reflow dom 元素 重绘 页面


原文地址:https://blog.csdn.net/u013100656/article/details/79888106

浏览器拿到HTML之后的渲染过程:
  1. 生成dom树;
  2. 生成render树;
  3. 执行reflow(在render树的基础上计算页面真实显示dom的位置);
  4. 执行repaint(为真实显示的dom绘制不影响dom位置的样式,如设置dom的color等)。
reflow:

当页面发生的某些变化影响了布局,需要倒回去重新渲染,该过程称为reflow(重排/回流)。reflow几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显示与隐藏)等,都将引起浏览器的reflow。只要这些变化引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染。通常我们无法预估浏览器到底会reflow哪一部分的代码,它们彼此相互影响。

repaint:

如果页面的变化只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器repaint(重绘)。

简而言之,如果页面的变化会导致dom的位置发生变化,则会触发reflow,如果不会导致dom的位置发生变化,则会触发repaint。如果触发了reflow则一定会触发repaint,而触发repaint则不一定会触发reflow。另外,reflow的成本比repaint高很多,dom树里每个结点的reflow都可能触发其子结点、祖先结点、兄弟结点的reflow。reflow过于频繁是导致页面性能下降的关键因素之一(也是页面性能优化的主要方向)。


要降低触发reflow的频率,首先要明确哪些情况会触发reflow,以下是会触发reflow的几种动作:

  1. 改变窗囗大小;
  2. 改变文字大小;
  3. 添加/删除样式表;
  4. 内容的改变,如用户在输入框中输入信息;
  5. 激活伪类,如:hover;
  6. 操作class属性;
  7. 脚本操作dom;
  8. 获取dom的offsetWidth和offsetHeight;
  9. 设置style属性。

reflow的优化:

  1. 尽可能限制reflow的影响范围,修改dom层级较低的结点。不要通过父级元素影响子元素样式。最好直接加在子元素上。改变子元素样式尽可能不要影响父元素和兄弟元素的尺寸;
  2. 不要一条一条的修改dom的样式,最好通过设置class的方式。 避免重复触发reflow和repaint;
  3. 经常reflow的元素,比如动画,position设为fixed或absolute,使其脱离文档流,不影响其它元素的布局;
  4. 权衡速度的平滑。比如实现一个动画,以1px为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多;
  5. 不要用tables布局。tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围;
  6. 避免使用css expression(每次都会重新计算);
  7. 减少不必要的dom层级(DOM depth)。改变dom树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行reflow上面;
  8. 避免不必要的复杂的css选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的cpu;
  9. 尽量不要频繁的增加、修改、删除元素,可以先把dom节点抽离到内存中进行复杂的操作然后再display到页面上。(display:none的节点不会被加入render树,而visibility:hidden会;display:none会触发reflow,而visibility:hidden只会触发repaint,因为layout没有变化)。

标签:触发,repaint,reflow,dom,元素,重绘,页面
来源: https://blog.csdn.net/lqlqlq007/article/details/93081165

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有