【发布时间】:2018-08-12 14:27:01
【问题描述】:
在实践中,我试图了解 Chrome 的布局 → 绘制 → 复合管道是如何工作的。在我的测试过程中,我对 Chrome 在以下情况下的行为感到困惑。 (Codepen)
var button = document.querySelector('button');
var red = document.querySelector('.red');
var blue = document.querySelector('.blue');
button.addEventListener('click', function() {
red.classList.toggle('test');
})
.wrapper {
height: 100%;
width: 100%;
background-color: teal;
position: static;
}
.square {
height: 200px;
width: 200px;
position: static;
transition: transform 0.3s ease,
opacity 0.3s ease,
width 0.3s ease,
height 0.3s ease,
box-shadow 0.3s ease;
}
.red {
/* position: absolute; */
background-color: red;
top: 100px;
left: 100px;
/* will-change: transform; */
opacity: 1;
}
.blue {
background-color: blue;
z-index: 3;
}
.test {
/* transform: translate3d(50px, 50px, 0); */
/* opacity: 0; */
width: 60px;
height: 60px;
/* box-shadow: 0px 0px 0px 10px rgba(0,0,0,.5) */
}
button {
position: fixed;
right: 100px;
top: 50px;
z-index: 10000;
font-weight: bold;
background-color: yellow;
padding: 5px 10px;
/* will-change: transform; */
}
<div class="wrapper">
<div class="red square"></div>
<div class="blue square"></div>
</div>
<button>Click</button>
复制。
- 使用 Chrome;
- 在开发工具中打开高亮重绘;
- 打开图层面板;
- 点击黄色按钮切换红色方块的大小;
- 查看突出显示为“重绘”的内容以及当前图层;
- 把红色方块的
position也改一下试试。
我们有两个正方形,一个红色的和一个蓝色的,在一个包装元素内。在 Chrome 的 Layers 面板中,这整件事显示为一层。
-
1234563元素在同一层,改变一个的尺寸,改变整个层的最终结果,所以必须重新绘制整个层。
如果我将红色方块设置为
absolute定位(您可以通过取消注释.red样式规则中的行来做到这一点),当我转换它的宽度和高度时,即使开发工具仍然显示一层,只有该层内的红色方块显示为重新绘制。
问题。
第二种情况对我来说没有意义。
如果两个方块和包装器元素都在同一层,不应该改变一个元素影响整个图层并导致整个图层重新绘制,而不仅仅是红色方块?
其他问题。
Chrome 是否在布局阶段(或确定层的任何阶段)将一些元素分成它们自己的层(例如,由于position 属性)?这就是为什么它能够单独重新粉刷它们吗?是否在合成阶段之后转储它们,因此开发人员只能在开发工具中看到一层?
相关背景。
我对现代浏览器的绘制过程粗略理解如下:
- 在布局阶段,浏览器将 CSS 与 HTML 信息相结合,以便确定屏幕上可视元素的位置和尺寸。我也相信这是它决定有多少渲染层的时间(例如,由于
will-change)。 - 在绘制阶段,浏览器会根据布局数据为每个图层创建一个帧缓冲区,其中包含有关每个像素应显示什么颜色的信息。
- 在合成阶段,GPU 根据绘制阶段生成的数据将所有图层合成在一起,并将最终结果发送到屏幕。
【问题讨论】:
-
您需要在您的问题中发布一个完整但最小的问题标记或代码示例,以便我们复制问题,而不是 Codepen 或任何其他第三方网站,:minimal reproducible example
-
你能澄清一下你的问题吗?您是在问整个过程是如何进行的吗? (需要几本书来解释这一切),还是你真的只关心你的
position: absolute案例? (如果是这样,在网上简单搜索一下就足够了:w3.org/TR/CSS2/visuren.html#absolute-positioning) -
@Kaiido 我试着澄清一下。是的,我想我是在询问整个过程,
position: absolute只是一个例子。我的问题的本质是为什么我只看到整个图层中的一个元素被重新绘制而不是整个图层。也许我问错了,我不知道。 -
OP 询问了这个问题on meta。 (/cc @Rob)
标签: css google-chrome browser google-chrome-devtools repaint