重绘和回流 及减少重绘和回流的方式
Posted 奥特曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重绘和回流 及减少重绘和回流的方式相关的知识,希望对你有一定的参考价值。
重绘和回流是前端经常听到的一个概念,这就涉及到了从html代码到浏览器的一个渲染过程。
我们还听到过一个概念叫重排,其实和回流是一个意思。
(1)前景
从浏览器的渲染引擎开始,首先会将HTML文档解析成 DOM Tree,与此同时,会将CSS文档解析成CSSOM,最后进行一个拼接,拼接成render Tree
(2)重绘
重绘,就像涂色一样,只修改一个元素的颜色,并不修改它的结构,就是重绘。
(3)回流/重排
当元素的宽高大小、隐藏显示,只要涉及到影响网页的布局就会触发回流,触发回流的同时必定引起重绘,但重绘不会引起回流。
在浏览器第一次加载时,就会产生一次回流 这也是开销非常大的。
触发回流
1.浏览器第一次加载
2.元素隐藏、显示
3.改变元素大小
4.元素位置发生改变
总结:只要不影响布局 只影响 元素颜色都会触发重绘,只要影响布局就会触发回流,触发回流的同时也会触发重绘
减少触发回流重绘的方式
(1)当用js代码多次修改结构样式时,每一行js代码都会产生一次回流(特指修改样式结构),不如添加一个类 用类名去控制样式。(包括用css一条一条修改样式结构)
(2)避免使用表格 修改一行表格的大小时 其他行、列的大小也会受影响
(3)复杂动画效果,使用绝对定位让其脱离文档流
(4)用transform:translate 代替 position left、right...
场景 两秒后移动元素的位置,首先用 定位 再用transform
<style>
div {
width: 100px;
height: 100px;
background: pink;
position: absolute;
}
</style>
</head>
<div></div>
<body>
<script>
let div = document.querySelector('div')
setTimeout(() => {
div.style.left=100+'px'
}, 2000);
</script>
</body>
发现 2秒左右时触发了 重排和重绘 接下来再看 transform
<style>
div {
width: 100px;
height: 100px;
background: pink;
transform: translateX(0);
}
</style>
</head>
<div></div>
<body>
<script>
let div = document.querySelector('div')
setTimeout(() => {
div.style.transform='translateX(100px)'
}, 2000);
</script>
</body>
这次再来看 发现 没有触发 重排和重绘,这也是transform动画是由GPU控制的,GPU是在组合线程上执行的,而其他是在主线程执行的,主线程执行会将页面绘制成一张位图或多张位图发送给组合线程,而组合线程会将主线程上的位图显示出来。
(5)离线后修改 一开始先隐藏 给样式都修改完后 在显示出来
(6)避免循环DOM元素 每次渲染一次DOM就会发生重绘重排一次
(7)利用文档碎片添加元素 (DocumentFragment不是真实的DOM,不会每次触发渲染,可以理解为 可以将所有的DOM进行收集起来,最后直接插入到浏览器中)
<body>
<ul class="list"></ul>
<script>
const list = document.querySelector('.list')
const fruits = ['A','B','C','D']
const fragment = document.createDocumentFragment()
fruits.forEach(fruit=>{
const li = document.createElement('li')
li.innerHTML=fruit
fragment.appendChild(li)
})
list.appendChild(fragment)
</script>
</body>
以上是关于重绘和回流 及减少重绘和回流的方式的主要内容,如果未能解决你的问题,请参考以下文章