我有许多正在制作动画的元素,我以一种不应导致任何浏览器绘制的方式开发这些元素。如果我在 Chrome Devtools 中打开“Paint Flashing”,我根本看不到任何油漆闪烁。然而,如果我记录表演,那么图表显示有很多时间花在绘画上。 FPS 有时低至 15fps。
我实际上是在 Vue 中构建的,编译后的代码导致太多代码无法粘贴到这里。我意识到动画有些损坏,我仍然需要计算一些时间等 - 但就这个问题而言,我只关心性能。
我已经在 CodePen 上发布了编译后的代码:
https://codepen.io/IOIIOOIO/pen/gjBqyg
似乎 StackOverflow 要求我在这里发布一些代码,所以这里是一个元素的编译代码:
.circle {
position: relative;
width: 100%;
padding-top: 100%;
border-radius: 50%;
overflow: hidden;
}
.circle::before {
content: "";
background-color: black;
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
animation-name: switch;
animation-iteration-count: infinite;
animation-timing-function: steps(1);
animation-duration: 3s;
animation-delay: inherit;
}
.rotating-circle {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
}
.rotating-circle--first-cycle {
background-color: black;
animation-name: rotate, toggle-first;
animation-duration: 3s, 3s;
animation-iteration-count: infinite, infinite;
animation-timing-function: linear, steps(1);
animation-delay: 1800ms;
}
.rotating-circle--second-cycle {
opacity: 0;
animation-name: rotate, toggle-second;
animation-duration: 3s, 3s;
animation-iteration-count: infinite, infinite;
animation-timing-function: linear, steps(1);
animation-delay: 1800ms;
}
@keyframes rotate {
0% {
transform: rotate3d(0, 1, 0, 0deg);
}
50% {
transform: rotate3d(0, 1, 0, 180deg);
}
}
@keyframes toggle-first {
0% {
opacity: 1;
}
25% {
opacity: 0;
}
75% {
opacity: 1;
}
}
@keyframes toggle-second {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
75% {
opacity: 0;
}
}
@keyframes switch {
0% {
transform: translatex(0);
}
50% {
transform: translatex(100%);
}
100% {
transform: translatex(0);
}
}
<div class="circle" style="background-color: rgb(255, 0, 0); animation-delay: 0ms;">
<div class="rotating-circle rotating-circle--first-cycle" style="animation-delay: 0ms;">
</div>
<div class="rotating-circle rotating-circle--second-cycle" style="background-color: rgb(255, 0, 0); animation-delay: 0ms;">
</div>
</div>
最佳答案
似乎所有工作都是在 Composite Layers
上完成的,不一定是在 Painting
上完成的。我发现将 transform: translateZ(0)
或 will-change
添加到动画中的单个元素并没有太大帮助。但是,如果我将 transform: translateZ(0)
添加到父 .circle
元素,那么在 Composite Layers
和 Painting 上花费的时间
大大减少。
它仍然运行得相当慢,但我认为这可能只是因为我的计算机具有板载显卡和 4GB 内存。
所以我认为这已经很好了,但如果有任何进一步的建议,我将不胜感激。
这是一个示例,其中我将 transform: translateZ(0)
添加到父元素:
https://codepen.io/IOIIOOIO/pen/gjBqyg
编辑:
通过删除父级上的 border-radius
,我发现了一个显着的改进,我将其设置为 overflow: hidden
以创建一个掩码:
之前:
.circle {
border-radius: 50%;
overflow: hidden;
}
相反,我使用 clip-path 作为 mask :
之后
transform: translateZ(0);
clip-path: circle(49% at 50% 50%);
我相信您会立即注意到它好多了:
https://codepen.io/IOIIOOIO/pen/OwBBJV
如能深入了解为何如此有效,我们将不胜感激。
关于performance - 糟糕的 CSS 动画性能 - 没有浏览器绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51741818/