会引起元素位置变化的就会重排,如窗口大小改变、字体大小改变、以及元素位置改变,都会引起周围的元素改变他们以前的位置;不会引起位置变化的,只是在以前的位置进行改变背景颜色等,只会重绘;
重排必将引起重绘,重绘不一定会引起重绘
重排的操作:
页面首次渲染
浏览器窗口大小发生改变
元素尺寸或位置发生改变
元素内容变化(文字数量或图片大小等等)
元素字体大小变化
添加或者删除可见的DOM元素
激活CSS伪类(例如::hover)
查询某些属性或调用某些方法
重绘: color、background-color、visibility 等
重排比重绘的代价要高 有时即使重排一个单一的元素,元素的父级和跟随它的元素也会跟着重排
现代浏览器自带的会对频繁的重排重绘进行优化,浏览器会维护一个任务队列,并设置一个阈(yu)值(可以是任务数量或者时间间隔),达到这个值的时候浏览器会将队列清空,一次性处理,将多次重排重绘变成一次。
触发浏览器清空队列的方法|属性:
clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
width、height
getComputedStyle()
getBoundingClientRect()
清空队列是为了确保返回值是最准确的,不清空重排重绘有可能会影响到这些属性方法
css
不使用Table布局,是普通布局的3倍损耗。
尽可能的在最末端改变class(元素自身)
避免设置多层内联样式
动画效果应用在absolute或fixed的元素上(脱离文档流,不会影响到外部)
少用css表达式:calc()
启动GPU加速:translate3d | translateZ | rotate | scale
js
不频繁的操作样式,一次性处理
不频繁操作dom,用documentFragment(文档片段),操作完在添加到真实Dom中
使用display: none,隐藏过程操作不会触发重排重绘,操作结束在显示(最终触发两次)
避免频繁读取会引发回流/重绘的属性,多次使用用一个变量缓存起来。