前言
前段时间,用vue作了一个吸顶等功能,实现这个功能会涉及到监听页面滚动,天然而言就会涉及到读取相关属性,频繁的读取属性,会致使reflow,也就会影响页面的性能,为了后面开发过程当中,尽可能写出更优的代码,所以总结一下回流和重绘的相关知识点css
浏览器的渲染过程
要了解回流和重绘,首先要知道浏览器客户端的渲染过程,主要分为如下步骤:vue
- 解析HTML生成DOM树
- 解析CSS生成CSSDOM规则树
- 将CSSDOM规则树和DOM树合并成一个Render Tree
- 根据Render Tree来布局,计算每一个节点的大小位置信息
- 将Render Tree每一个节点绘制到屏幕
什么是回流(reflows)
回流(reflows)是指网络浏览器为了从新渲染部分文档或者所有文档而从新计算文档中元素的位置和几何结构的过程,简单来讲,就是页面上某些元素的大小、位置或者显示隐藏等发生改变致使页面从新构建的过程浏览器
什么是重绘(repaints)
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并从新绘制它,这个过程称为重绘。缓存
特色:回流必将引发重绘,重绘不必定引发回流 回流比重绘的代价更高网络
什么会致使回流(reflows)、重绘(repaints)?
如下状况会致使回流:布局
- 调整浏览器窗口大小
- 元素字体大小变化
- 脚本操做(添加或者删除)DOM(可见的,对display:none的元素进行操做不会引发回流、重绘)
- 元素的位置或者大小变化
- 内容改变引起的尺寸变化,如文本改变(用户在input框中输入文字)或者图片大小改变而引发的宽度和高度改变
- 激活CSS伪类(例如:hover)
- 计算 offsetWidth 和 offsetHeight 属性等
一些经常使用且会致使回流的属性和方法:性能
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- scrollIntoView()、scrollIntoViewIfNeeded()、scrollTo
- getComputedStyle()、getBoundingClientRect()
如何避免回流、重绘?
1. css
- 避免使用table布局
在布局完成以前,table常常须要多个关口,由于table能够影响在它以前进入DOM的元素的显示。例如,因为表格的最后的一行内容过长而致使纵列大小的彻底改变。另外还有一点就是,即便一些小的变化将致使表格(table)中的全部其余节点回流。
- 牺牲平滑度换取速度
意思是指您可能想每次1像素移动一个动画,可是若是此动画及随后的回流使用了100%的CPU,动画就会看上去是跳动的,由于浏览器正在与更新回流作斗争。动画元素每次移动3像素可能在很是快的机器上看起来平滑度低了,但它不会致使CPU在较慢的机器和移动设备中抖动。
- 将动画效果应用到position属性为absolute或fixed的元素上
他们不会影响其余元素的布局,不会致使回流,性能消耗更低
- 避免使用CSS的JavaScript表达式 (仅 IE 浏览器),如calc()
- 避免设置多项内联样式
经过style属性设置会致使回流,避免设置多项内联样式(不要一个一个改变元素的样式属性),由于每次都会形成回流,样式应该合并在一个外部类(class),直接操做改class,只会产生一次回流
- 尽量在DOM树的最末端改变class
回流能够自上而下,或自下而上的回流的信息传递给周围的节点。回流是不可避免的,但能够减小其影响。尽量在DOM树的里面改变class,能够限制了回流的范围,使其影响尽量少的节点。例如,应该避免经过改变父类去影响子节点的显示。
2. js
- 避免频繁操做DOM,改善DOM操做致使的回流
(1)让要操做的元素进行离线处理(即让元素不存在与Render Tree中),处理完后一块儿更新
- 使用documentFragment进行缓存操做,引起一次回流和重绘(主要用于添加元素,先把全部须要添加的元素添加到一个容器 内,而后再添加到body中)
- 使用display:none 技术(先display:none隐藏元素,而后对元素进行操做,而后显示元素)
- 使用cloneNode(true or false) 和 replaceChild 技术
(2)不要常常访问会引发浏览器flush队列的属性,若是你确实要访问,利用缓存
(3)不要一个一个改变元素的样式属性,直接改变className,若是动态改变样式,则使用cssText
(4)让元素脱离动画流(应用到position属性为absolute或fixed的元素),减小回流的Render Tree的规模字体