CSS动画性能不佳-没有浏览器绘制

时间:2018-08-08 08:17:45

标签: performance animation css-animations

我正在制作许多动画元素,这些元素的开发方式不会引起任何浏览器绘制。如果我在Chrome Devtools中启用“绘画闪烁”,则根本看不到任何绘画闪烁。但是,如果我记录下性能,则该图将显示有很多时间花在绘画上。 FPS有时低至15fps。

我实际上是在Vue中构建的,编译后的代码导致太多代码无法粘贴到此处。我意识到动画有些破损,我仍然需要计算一些时间安排-但是出于这个问题的目的,我只关心性能。

我已将编译后的代码发布到了CodePen上:

https://codepen.io/IOIIOOIO/pen/OwBBJV

似乎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>

1 个答案:

答案 0 :(得分:1)

似乎所有工作都在Composite Layers上完成,而不一定在Painting上完成。我发现将transform: translateZ(0)will-change添加到动画元素中并没有多大帮助。但是,如果我将transform: translateZ(0)添加到父元素.circle,则在Composite LayersPainting上花费的时间将大大减少。

它仍然运行相当慢,但是我认为这可能是因为我的计算机具有板载图形和4GB RAM。

因此,我认为这虽然会尽善尽美,但希望您能提出任何进一步的建议。

以下是我将transform: translateZ(0)添加到父元素的示例:

https://codepen.io/IOIIOOIO/pen/gjBqyg

编辑:

我发现通过移除父级上的border-radius来创建蒙版的overflow: hidden有了显着改善:

之前:

.circle {
  border-radius: 50%;
  overflow: hidden;
}

相反,我使用剪切路径作为遮罩:

之后

  transform: translateZ(0);
  clip-path: circle(49% at 50% 50%);

我敢肯定,您会立即注意到它会更好:

https://codepen.io/IOIIOOIO/pen/OwBBJV

任何对此工作原理的进一步了解将不胜感激。