什么是回流和重绘:

***什么是渲染树:

DOM树和CSSOM树结合。

***回流:

当渲染树(render tree)一部分(或全部)元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流。

每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的。

***如果再具体一点:

通过构造渲染树,我们将可见DOM节点以及它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流。

为了弄清每个对象在网站上的确切大小和位置,浏览器从渲染树的根节点开始遍历。

***重绘:

当一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的。

比如background-color。这就叫称为重绘。

***区别与联系:

回流必将引起重绘,而重绘不一定会引起回流。

比如:只有颜色改变的时候就只会发生重绘而不会引起回流,

当页面布局和几何属性改变时就需要回流

***比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变

***优化:

——首先我们要知道:由于浏览器每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。

浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。

但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:

offsetTop、offsetLeft、offsetWidth、offsetHeight

scrollTop、scrollLeft、scrollWidth、scrollHeight

clientTop、clientLeft、clientWidth、clientHeight

getComputedStyle()

getBoundingClientRect

1:最好避免使用上面列出的属性,它们都会刷新渲染队列。

2:合并多次对DOM和样式的修改,然后一次处理掉(最小化重绘和重排)

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

也可以这样:el.className += ' active';

3:使元素脱离文档流(减少回流)

4:避免触发同步布局事件(访问元素的一些属性的时候,会导致浏览器强制清空队列,进行强制同步布局),例子:

不推荐写法:

function initP() {

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

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

    }

}

推荐写法:

const width = box.offsetWidth;

function initP() {

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

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

    }

}

5:CSS3硬件加速(GPU加速)(根本不要回流重绘)

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

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

常见的触发硬件加速的css属性:transform,opacity,filters,Will-change

缺点:

如果为太多元素使用css3硬件加速,会导致内存占用较大,会有性能问题。

在GPU渲染字体会导致抗锯齿无效。这是因为GPU和CPU的算法不同。因此如果不在动画结束的时候关闭硬件加速,会产生字体模糊。

顺藤摸瓜(何为复合图层):

一般一个元素开启硬件加速后会变成复合图层,可以独立于普通文档流中,改动后可以避免整个页面重绘,提升性能

但是尽量不要大量使用复合图层,否则由于资源消耗过度,页面反而会变的更卡

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容