Appearance
18.什么是重绘和回流?
- 重排(回流)
Reflow
: 添加元素、删除元素、修改大小、移动元素位置、获取位置相关信息 - 重绘
Repaint
:页面中元素样式的改变并不影响它在文档流中的位置。
我们应当尽可能减少重绘和回流。
1.强制同步布局问题
JavaScript 强制将计算样式和布局操作提前到当前的任务中
html
<div id="app"></div>
<script>
function reflow() {
let el = document.getElementById('app');
let node = document.createElement('h1');
node.innerHTML = 'hello';
el.appendChild(node);
// 强制同步布局
console.log(app.offsetHeight);
}
requestAnimationFrame(reflow)
</script
<div id="app"></div>
<script>
function reflow() {
let el = document.getElementById('app');
let node = document.createElement('h1');
node.innerHTML = 'hello';
el.appendChild(node);
// 强制同步布局
console.log(app.offsetHeight);
}
requestAnimationFrame(reflow)
</script
2.布局抖动(layout thrashing)问题
在一段 js 代码中,反复执行布局操作,就是布局抖动
js
function reflow() {
let el = document.getElementById("app");
let node = document.createElement("h1");
node.innerHTML = "hello";
el.appendChild(node);
// 强制同步布局
console.log(app.offsetHeight);
}
window.addEventListener("load", function () {
for (let i = 0; i < 100; i++) {
reflow();
}
});
function reflow() {
let el = document.getElementById("app");
let node = document.createElement("h1");
node.innerHTML = "hello";
el.appendChild(node);
// 强制同步布局
console.log(app.offsetHeight);
}
window.addEventListener("load", function () {
for (let i = 0; i < 100; i++) {
reflow();
}
});
3.减少回流和重绘#
- 脱离文档流
- 渲染时给图片增加固定宽高
- 尽量使用 css3 动画html
<style> /* ctrl+shift+p (show Rending 查看重绘操作) */ @keyframes rotate { from { transform: rotate(0deg); /* width: 100px; */ } to { transform: rotate(360deg); /* width: 500px; */ } } #app { width: 100px; height: 100px; background: red; animation: rotate 0.2s linear infinite; } </style> <div id="app"></div>
<style> /* ctrl+shift+p (show Rending 查看重绘操作) */ @keyframes rotate { from { transform: rotate(0deg); /* width: 100px; */ } to { transform: rotate(360deg); /* width: 500px; */ } } #app { width: 100px; height: 100px; background: red; animation: rotate 0.2s linear infinite; } </style> <div id="app"></div>
- 可以使用 will-change 提取到单独的图层中html
<div style="will-change: transform">我是单独的图层</div>
<div style="will-change: transform">我是单独的图层</div>