transform/opacity 属性 是否在浏览器传送带中调用绘制步骤
Does transform/opacity property invoke paint step in the browser conveyor
调查浏览器的渲染如何工作我注意到在 chrome 开发工具中启用标志 paint flashing
触发绘制步骤更改 transform/opacity
属性.
使用代码查看这些屏幕截图:
示例 1 (transform/opacity
属性)
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.transform = `translate(${count}px,0)`;
/// interchangeable
/// elem.style.opacity = `${count/500}`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
示例 2(transform/opacity
属性 和 will-change
)
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.transform = `translate(${count}px,0)`;
/// interchangeable
/// elem.style.opacity = `${count/500}`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
will-change: transform;
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
这让我很困惑,因为我看过 this one and this one 消息来源,他们说当你使用 transform/opacity
时,绘画阶段被忽略了。那是什么?为什么我们在第一个示例中看到油漆,而在第二个示例中看不到?哪个在说谎?
一个有趣的示例,包含 2 个绘画操作:
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.left = `${count}px`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
是的,使用了属性的定位,但是看paint的操作,一大一小比如没有will-change
的例子。这是什么意思(我说的是条纹长度很小的油漆)?
小的颜料块和光栅线有关吗,大的呢?
两个例子都没有说谎。
浏览器最大限度地减少了需要合成在一起的层数。如果有理由相信会有好处,它只会创建一个层。
如果您使用 CSS 过渡、CSS 动画或网络动画为变换或不透明度设置动画,浏览器会提前知道该元素正在以一种可以通过创建优化的方式进行动画处理一层,所以 Chrome 在动画持续时间内创建一层。
如果您使用 rAF 制作动画,浏览器就没有这种先见之明。 will-change
的存在是为了向浏览器提示它应该根据不断变化的 属性.
为此元素创建一个图层。
这些是提示,浏览器不能保证创建图层。在其他情况下,某些浏览器会创建图层,例如当另一个元素需要在图层顶部绘制时,以及在某些其他 CSS 的情况下,例如 transform: translateZ(…)
.
调查浏览器的渲染如何工作我注意到在 chrome 开发工具中启用标志 paint flashing
触发绘制步骤更改 transform/opacity
属性.
使用代码查看这些屏幕截图:
示例 1 (transform/opacity
属性)
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.transform = `translate(${count}px,0)`;
/// interchangeable
/// elem.style.opacity = `${count/500}`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
示例 2(transform/opacity
属性 和 will-change
)
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.transform = `translate(${count}px,0)`;
/// interchangeable
/// elem.style.opacity = `${count/500}`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
will-change: transform;
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
这让我很困惑,因为我看过 this one and this one 消息来源,他们说当你使用 transform/opacity
时,绘画阶段被忽略了。那是什么?为什么我们在第一个示例中看到油漆,而在第二个示例中看不到?哪个在说谎?
一个有趣的示例,包含 2 个绘画操作:
let elem = document.querySelector(".newLayer");
let count = 0;
function anim(){
elem.style.left = `${count}px`;
if(count++ < 500)
requestAnimationFrame(anim);
}
anim();
.newLayer{
position:relative;
width:150px;
height:150px;
background-color: red;
}
<div class="newLayer">I am a new Layer</div>
是的,使用了属性的定位,但是看paint的操作,一大一小比如没有will-change
的例子。这是什么意思(我说的是条纹长度很小的油漆)?
小的颜料块和光栅线有关吗,大的呢?
两个例子都没有说谎。
浏览器最大限度地减少了需要合成在一起的层数。如果有理由相信会有好处,它只会创建一个层。
如果您使用 CSS 过渡、CSS 动画或网络动画为变换或不透明度设置动画,浏览器会提前知道该元素正在以一种可以通过创建优化的方式进行动画处理一层,所以 Chrome 在动画持续时间内创建一层。
如果您使用 rAF 制作动画,浏览器就没有这种先见之明。 will-change
的存在是为了向浏览器提示它应该根据不断变化的 属性.
这些是提示,浏览器不能保证创建图层。在其他情况下,某些浏览器会创建图层,例如当另一个元素需要在图层顶部绘制时,以及在某些其他 CSS 的情况下,例如 transform: translateZ(…)
.