reflow(回流)与repaint(重绘)的区别及优化

1.回流及重绘的概念javascript

回流(reflow):当render tree中的元素的宽高、布局、显示、隐藏或元素内部文字结结构发生改变时,会影响自身及其父元素、甚至追溯到更多的祖先元素发生改变,则会致使元素内部、周围甚至整个页面的从新渲染,页面发生重构,回流就产生了。css

重绘(repaint):元素的结构(宽高、布局、显示隐藏、内部文字大小)未发生改变,只是元素的外观样式发生改变,好比背景颜色、内部文字颜色、边框颜色等。此时会引发浏览器重绘,显然重绘的速度快于回流。html

回流必定会触发重绘,重绘不必定触发回流。java

2.回流重绘对性能的影响浏览器

这里了解一个知识点:渲染css样式会影响js执行的时间,使得加载js脚本变慢。缘由以下:dom

浏览器渲染一个网页的时候会启用两条线程:一条渲染javascript 脚本,另外一条渲染 ui 即css 样式的渲染。但这两条线程是互斥的,当javascript 线程运行的时候 ui 线程则会停止暂停,反之亦然。由于当ui 线程运行对页面进行渲染的时候, js 脚本不免会涉及到页面视图上的一些样式的改变,为了使这个改变动加准确 js 脚本只好等待ui 线程渲染完成的时候才去执行。ide

因此当一个页面的元素样式改动频繁的时候ui 线程就会持续渲染,形成js 代码反应慢半拍,卡顿的状况。回流和重绘都会使得ui线程渲染时间加长,太多就会使得网站性能变差,所以要尽可能减小reflow和repaint。布局

3.如何减小回流和重绘性能

 致使回流发生的状况以下:动画

  • 改变窗口大小
  • 改变文字大小
  • 内容的改变,如用户在输入框中敲字
  • 激活伪类,如:hover
  • 操做class属性
  • 脚本操做DOM
  • 计算offsetWidth和offsetHeight
  • 设置style属性

 对应的css属性以下:

  • 盒子模型相关属性
  • 定位及浮动属性
  • 节点内部的文字结构

  

 致使重绘的css属性以下:

  

 

  减小回流和重绘注意点以下:

1:用transform 代替 top,left ,margin-top, margin-left... 这些位移属性

2:用opacity 代替 visibility,可是要同时有translate3d 或 translateZ 这些能够建立的图层的属性存在才能够阻止回流

可是第二点通过个人实验,发现若是不加 transform: translateZ(0) 配合opacity的话仍是会产生回流的,而只用visibility 就只会产生重绘不会回流

而  opacity 加上 transform: translateZ/3d  这个属性以后便不会发生回流和重绘了

3:不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。

4:若是确实须要用 js 对 dom 设置多条样式那么能够将这个dom 先隐藏,而后再对其设置

5:不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight... 这些。浏览器有一个回流的缓冲机制,即多个回流会保存在一个栈里面,当这个栈满了浏览器便会一次性触发全部样式的更改且刷新这个栈。可是若是你屡次获取这些元素的实际样式,浏览器为了给你一个准确的答案便会不停刷新这个缓冲栈,致使页面回流增长。

因此为了不这个问题,应该用一个变量保存在循环体外。

6:不要使用table 布局,由于table 的每个行甚至每个单元格的样式更新都会致使整个table 从新布局

7:动画的速度按照业务按需决定。

8:对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签

9:必要时能够开启 GPU 加速,可是不能滥用

相关参考:

http://www.javashuo.com/article/p-xtoszrsh-gg.html

http://www.javashuo.com/article/p-tfclhmbv-dt.html

相关文章
相关标签/搜索