重排与重绘
一直都知道一次渲染与多次渲染必是一次更优 优在哪里呢?
浏览器加载css的步骤:
通常在文档初次加载时,
浏览器引擎构建DOM树,
根据DOM元素的几何属性构建一棵渲染树。
渲染树的每个节点都有大小和边距等属性,类似于盒子模型(由于隐藏元素不需要显示,渲染树中并不包含DOM树中隐藏的元素)。
当渲染树构建完成后,浏览器就可以将元素放置到正确的位置了,再根据渲染树节点的样式属性绘制出页面。
由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。
但table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,
通常要花3倍于同等元素的时间。
重排必引起重绘
重绘不一定重排
在现代浏览器中,渲染页面所要负责的线程主要有两个:主线程和排版线程。
- 运行js
- 计算元素css的样式
- 布局页面
- 把元素绘制成一个或多个位图
- 交给排版线程
- 通过GPU渲染位图 显示在屏幕上
- 向主线程请求更新位图的可见部分或即将可见的部分
- 判断当前页面处于可见部分
- 判断出即将通过页面滚动而可见的部分
- 随着用户滚动页面来移动这些部分
排版线程对于用户的操作保持快速的响应,普遍的效率时每秒 60 帧的速度去刷新显示。
实例1:
<style>
#foo {
height: 100px;
width: 100px;
background: red;
transition: height 1s linear;
}
#foo:hover {
height: 200px;
}
</style>
<body>
<div id="foo"></div>
</body>
主线程 | 排版线程 | 速度 |
---|---|---|
元素布局 | 慢 | |
将元素绘制成位图 | 载入到 GPU显存中 | 慢 |
开始CSSTransition | 绘制 | |
高度++ | ||
重新布局 | 慢 | |
将元素绘制成位图 | 载入到 GPU显存中 | 慢 |
... | ... | ... |
频繁重载 重绘
<style>
#foo {
height: 100px;
width: 100px;
background: red;
transition: transform 1s linear;
}
#foo:hover {
transform: scale(2);
}
</style>
<body>
<div id="foo"></div>
</body>
主线程 | 排版线程 | 速度 |
---|---|---|
元素布局 | 慢 | |
将元素绘制成位图 | 载入到 GPU显存中 | 慢 |
开始CSSTransition | 绘制 | |
通知 | 倍数++ | |
... | ... | ... |