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.如何减小回流和重绘性能
致使回流发生的状况以下:动画
对应的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 加速,可是不能滥用 |
相关参考: