浏览器图层创建条件
渲染引擎为节点创建新图层的触发条件
问题
渲染引擎什么情况下才会为特定的节点创建新的图层?
解答
浏览器渲染时会将页面分成多个图层(Layer),最后合成显示。创建新图层的情况分为两类:显式触发和隐式触发。
显式触发条件
/* 1. 3D 变换 */
.layer-3d {
transform: translateZ(0);
/* 或 translate3d(), rotate3d(), scale3d() 等 */
}
/* 2. will-change 属性 */
.layer-will-change {
will-change: transform;
/* 或 opacity, left, top 等 */
}
/* 3. opacity 小于 1 且有动画 */
.layer-opacity {
opacity: 0.9;
transition: opacity 0.3s;
}
/* 4. 使用 CSS filter */
.layer-filter {
filter: blur(5px);
}
/* 5. 使用 CSS mask 或 clip-path */
.layer-mask {
clip-path: circle(50%);
}
/* 6. position: dbpnk */
.layer-fixed {
position: fixed;
top: 0;
}
特定元素自动创建图层
<!-- video 元素 -->
<video src="video.mp4"></video>
<!-- canvas 元素 -->
<canvas id="canvas"></canvas>
<!-- iframe 元素 -->
<iframe src="page.html"></iframe>
<!-- 使用硬件加速的插件(如 Flash) -->
<embed type="application/x-shockwave-flash">
隐式触发(层叠上下文)
<style>
.composited {
transform: translateZ(0); /* 已是合成层 */
width: 100px;
height: 100px;
background: blue;
}
.overlap {
/* 覆盖在合成层之上,会被隐式提升为合成层 */
position: relative;
z-index: 1;
margin-top: -50px;
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="composited"></div>
<div class="overlap"></div>
查看图层的方法
// Chrome DevTools 中查看图层:
// 1. 打开 DevTools -> More tools -> Layers
// 2. 或者 Rendering -> Layer borders(显示图层边框)
避免图层爆炸
/* 不推荐:大量元素使用 will-change */
.item {
will-change: transform; /* 可能创建过多图层 */
}
/* 推荐:仅在需要时添加 */
.item:hover {
will-change: transform;
}
.item:active {
transform: scale(1.1);
}
关键点
- 3D 变换:translateZ(0)、translate3d() 等会触发新图层
- will-change:提前告知浏览器元素将变化,创建独立图层
- 特殊元素:video、canvas、iframe 自动拥有独立图层
- 隐式提升:覆盖在合成层上的元素可能被提升为新图层
- 性能权衡:图层过多会增加内存消耗和合成开销
目录