SVG动画:Chrome浏览器性能低下/性能不佳

时间:2018-11-20 18:37:32

标签: javascript css performance animation svg

我们正在开发一个相当复杂的场景,其中包含许多可移动的部分,到现在为止还没有涉及任何SVG动画。

一切都很顺利,并且表现良好,直到我们引入了带有一些虚线的SVG,并使用stroke-dashoffset属性对其进行了动画处理。

在Edge或Firefox中绝对没有区别,但是在Chrome中,整个场景的动画变得断断续续。

我们甚至都尝试过两种方法,即SVG元素内的CSS关键帧和SMIL,但两者的效果均不相同。

我们缺少Chrome的性能诀窍吗?

编辑:示例

标记:

.stream {
  animation: stream 10s infinite;
}

@keyframes stream {
  100% {
    stroke-dashoffset: 100;
  }
}
<svg version="1.0" id="streams" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 225.32 66.19" enable-background="new 0 0 225.32 66.19" xml:space="preserve">
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M107.38,50.54c0,0-6.78-84.52-106.51-22.2" />
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M110.49,45.31c-0.63-13.01-4.56-44.87-27.83-43.8c-27.6,1.27-37.33,39.66-38.49,60.34"/>
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M180.63,59.88c-0.69-9.65-3.6-30.18-15.76-45.51C148.44-6.34,131.85,2.22,128.87,5c-2.89,2.7-12.81,7.14-14.28,42"/>
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M118.59,45.41c2.4-10.18,9.9-31.97,30.87-37.59c26.03-6.98,55.13,9.32,72.02,19.37"/>
</svg>

2 个答案:

答案 0 :(得分:1)

您需要将动画的 ease 设置为linear。运行下面的代码片段,看看它运行时没有那种笨拙的减速。

.stream {
  animation: stream 10s linear infinite;
}

@keyframes stream {
  100% {
    stroke-dashoffset: 100;
  }
}
<svg version="1.0" id="streams" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 225.32 66.19" enable-background="new 0 0 225.32 66.19" xml:space="preserve">
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M107.38,50.54c0,0-6.78-84.52-106.51-22.2" />
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M110.49,45.31c-0.63-13.01-4.56-44.87-27.83-43.8c-27.6,1.27-37.33,39.66-38.49,60.34"/>
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M180.63,59.88c-0.69-9.65-3.6-30.18-15.76-45.51C148.44-6.34,131.85,2.22,128.87,5c-2.89,2.7-12.81,7.14-14.28,42"/>
      <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" d="M118.59,45.41c2.4-10.18,9.9-31.97,30.87-37.59c26.03-6.98,55.13,9.32,72.02,19.37"/>
</svg>

答案 1 :(得分:0)

How can I animate infinite marker movement down an SVG path without very high CPU usage?重复

这里真正的问题是不良的svg实现,请参见chrome bug

一种解决方法确实会降低JavaScript动画的帧速率,请参见代码示例

这种特殊情况可以用虚线圆和css transform: rotate3d()完成。但是在当今的svg实现中,“ GPU转换”的转换/旋转性能也很差。解决方法:将svg代码包装在<div>中,并对div进行动画处理,瞧! cpu降为零。相关:crmarsh.com/svg-performance

const svg_elem = document.getElementById('streams')

const animateDashTime = 200 // milliseconds
let anim_dash_offset = 0
let animateDashTimer = null

function animateDashStep(){

  anim_dash_offset += 1

  svg_elem.setAttribute('style',
    '--stroke-dashoffset: '+anim_dash_offset);

  // repeat
  animateDashTimer = setTimeout(
    animateDashStep,
    animateDashTime
  )
}

// start
animateDashStep()

// stop
//clearTimeout(animateDashTimer)
<svg version="1.0" id="streams" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 225.32 66.19" enable-background="new 0 0 225.32 66.19" xml:space="preserve" 

  style="--stroke-dashoffset: 0"
>
  <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" 
  
    stroke-dasharray="3,4" 
    stroke-dashoffset="var(--stroke-dashoffset)" 

    d="M107.38,50.54c0,0-6.78-84.52-106.51-22.2"
  />
  <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" stroke-dashoffset="var(--stroke-dashoffset)" d="M110.49,45.31c-0.63-13.01-4.56-44.87-27.83-43.8c-27.6,1.27-37.33,39.66-38.49,60.34"
  />
  <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" stroke-dashoffset="var(--stroke-dashoffset)" d="M180.63,59.88c-0.69-9.65-3.6-30.18-15.76-45.51C148.44-6.34,131.85,2.22,128.87,5c-2.89,2.7-12.81,7.14-14.28,42"/>
  <path class="stream" fill="none" stroke="#000" stroke-width="1.75" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="3,4" stroke-dashoffset="var(--stroke-dashoffset)" d="M118.59,45.41c2.4-10.18,9.9-31.97,30.87-37.59c26.03-6.98,55.13,9.32,72.02,19.37"/>
</svg>