我目前正在开始一个动画项目。在这个项目中,我将拥有超过40000个div
并对它们进行迭代动画。如果任何一个div
处于被动状态(即至少2秒内没有进行动画),我将不会显示它们以提高动画性能。
问题是:哪种CSS属性最适合这种情况?
.passive1{
display:none
}
.passive2{
visibility:hidden;
}
.passive3{
opacity:0;
}
我该如何衡量渲染性能,例如帧率和GPU使用情况?
我目前正在开始一个动画项目。在这个项目中,我将拥有超过40000个div
并对它们进行迭代动画。如果任何一个div
处于被动状态(即至少2秒内没有进行动画),我将不会显示它们以提高动画性能。
问题是:哪种CSS属性最适合这种情况?
.passive1{
display:none
}
.passive2{
visibility:hidden;
}
.passive3{
opacity:0;
}
我该如何衡量渲染性能,例如帧率和GPU使用情况?
虽然这三个属性都会使元素的框看起来似乎是不可见的,但它们之间存在着关键性的差异:
属性 | 是否绘制 | 参与布局 | 形成堆叠上下文 | 响应指针事件 | 响应键盘事件 |
---|---|---|---|---|---|
opacity: 0; |
否 | 是 | 新的 | 是 | 是 |
visibility: hidden; |
否 | 是 | 不确定 | 否 | 否 |
display: none; |
否 | 否 | 不确定 | 否 | 否 |
background-image
)、#text
内容等等。display: none;
才是“否”,因为使用opacity: 0;
和visibility: hidden;
时,浏览器仍然需要确定元素的大小以便正确布局其他元素(例如,如果你有span.hidden { visibility: hidden; display: inline; }
)。opacity
(除了opacity: 1.0;
)都将创建一个新的堆叠上下文,这会使position
属性的使用变得更加复杂。visibility: hidden;
,则:hover
状态无法生效,点击同一元素也不会应用:focus
或:active
。visibility: hidden;
不会触发mouseclick
、touchstart
等事件——请注意,某些元素(如<button>
)仍然可以引发click
事件,如果用户使用非指针输入方法(如键盘或语音(可访问)导航方式),则可以激活该元素。
pointer-events: none;
来阻止指针事件,但这不会阻止键盘和其他非指针输入,因此不应将其用这张表格展示了这三个属性的主要值之间更完整的比较:
属性 | 是否绘制 | 在布局中 | 层叠上下文 | 指针事件 | 键盘事件 | 可动画化 |
---|---|---|---|---|---|---|
不透明度 | ||||||
opacity: 0; |
不 | 是 | 新的 | 是 | 是 | 是 |
opacity: 0.1; |
是 | 是 | 新的 | 是 | 是 | 是 |
opacity: 0.9; |
是 | 是 | 新的 | 是 | 是 | 是 |
opacity: 1; |
是 | 是 | 各不相同 | 是 | 是 | 是 |
可见性 | ||||||
visibility: hidden; |
不 | 是 | 各不相同 | 不 | 不 | 是,有限制 |
visibility: visible; |
是 | 是 | 各不相同 | 是 | 是 | 是,有限制 |
显示方式 | ||||||
display: none; |
不 | 不 | 各不相同 | 不 | 不 | 不 |
display: contents; |
仅文本和子元素 | 仅文本和子元素 | 各不相同 | 是 | 是 | 不 |
其他 | ||||||
pointer-events: none; |
N/A | N/A | N/A | 不 | 是 | 不 |
“Animatable”列指示该属性是否可以与CSS过渡(transition:
)或CSS动画(@keyframes
)一起使用。
display:
属性无法进行动画处理,这就是为什么我们不能使用@keyframes
时间轴在动画完成后完全隐藏元素的原因。
visibility:
属性,虽然有限制条件。此外,请勿混淆类似命名的backface-visibility
和content-visibility
属性。
backface-visibility
仅适用于3D transform
操作。content-visibility
是加速页面加载的优化,但需要首先使用CSS Containment,这超出了本问答的范围。display:none
会隐藏整个元素并将其从布局空间中移除,而visibility:hidden
会隐藏元素但仍占用与之前相同的空间。
如果您想创建透明度或淡入淡出效果,可以使用不透明度。
display:none
是因为div被取出了流,因此它们的位置不需要计算。
话虽如此,40000个div听起来很疯狂。你有考虑过像HTML5画布或SVG这样的替代方案吗?
我如何测量渲染性能,例如fps、gpu使用率?
- Cihad Turhanvisibility:hidden;
opacity:0;
transition: all .3s;
visibility:visible;
opacity:1;
在调查Safari移动版本中的hover bug时发现了这个帖子。
确认opacity: 0
是一个有效的方法(在我的情况下是这样,谢谢大家)。opacity: 0
修复了足够的问题,使其可行(仍然需要在屏幕旋转[宽度变化]时进行烦人的js重绘)。
关于我用opacity: 0
修复的bug的背景信息:
hover位于包含一个div的li上,在悬停(或单击移动设备上的)日历条目时显示。在Safari移动版中真的很随机,有时工作,有时不工作 - 更奇怪的是,行为会随着屏幕旋转而改变++ [注意:没有涉及媒体查询,因此不是这种情况]。
如此烦人,因为在我尝试的所有其他浏览器中都正常工作。