css3动画会造成回流重绘吗,网页性能篇——回流与重绘

一、浏览器渲染的过程

解析HTML,构建DOM树。解析CSS,构建CSSOM树

DOM树和CSSOM树结合,生成渲染树

回流(Layout):根据生成的渲染树进行回流,得到节点的几何信息(大小和位置)

重绘(Painting): 根据渲染树以及已经得到的回流信息,得到节点的绝对像素。

将像素发送给GPU,展现在页面上

二、什么时候会发生回流与重绘

回流这一阶段主要是计算位置与几何信息,所以当页面布局和几何信息发生变化的时候就需要回流 。比如以下情况

页面一开始渲染的时候

浏览器的窗口发生变化(会重新计算位置和大小)

添加或删除可见的DOM元素

元素的大小(width,height,margin,padding,border-width),位置发生变化

内容发生变化(如图片的url改变)

只发生重绘的情况:改变一些只影响元素外观的样式,而不影响布局(如background改变)

三、浏览器触发回流与重绘

当浏览器获取布局信息时,由于要获取最新的布局信息,所以浏览器不得不清空队列,触发回流重绘来返回准确的值。如修改下面的值:

offset~ (offsetTop、offsetLeft、offsetWidth、offsetHeight)

scroll~ (scrollTop、scrollLeft、scrollWidth、scrollHeight)

client~ (clientTop、clientLeft、clientWidth、clientHeight)

getComputedStyle()

getBoundingClientRect

三、如何减少回流与重绘

1.合并多次对样式的修改

如:

const el = document.getElementById('test');

el.style.padding = '5px';

el.style.borderLeft = '1px';

el.style.borderRight = '2px';

可以使用cssText合并所有的改变,然后一起处理

const el = document.getElementById('test');

el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';

或者通过改变className改变样式

const el = document.getElementById('test');

el.className += ' active';

2. 批量修改DOM

如:

function appendDataToElement(appendToElement, data) {

let li;

for (let i = 0; i < data.length; i++) {

li = document.createElement('li');

li.textContent = 'text';

appendToElement.appendChild(li);

}

}

上面代码每一次循环都添加了DOM元素,所以导致了很多次的回流与重绘

所以可以先创建完所有的元素后一次性添加

const ul = document.getElementById('list');

const fragment = document.createDocumentFragment();

appendDataToElement(fragment, data);

ul.appendChild(fragment);

3.避免触发同步布局事件

上文我们提到过,访问一些属性时会导致浏览器强制清空队列,如使用offsetWidth:

function initP() {

for (let i = 0; i < paragraphs.length; i++) {

paragraphs[i].style.width = box.offsetWidth + 'px';

}

}

上面代码每一次循环都访问了offsetWidth,所以导致了很多次的回流与重绘

所以我们要尽量减少访问这类属性

function initP() {

const width = box.offsetWidth;

for (let i = 0; i < paragraphs.length; i++) {

paragraphs[i].style.width = width + 'px';

}

}

4.对于复杂动画效果,使用绝对定位让其脱离文档流

5.css3硬件加速(GPU加速)

比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘。

使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。

对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。

你可能感兴趣的:(css3动画会造成回流重绘吗)