动画和模糊内容的GPU加速

8

问题: 当应用模糊效果到一个动画对象时,我的 CPU 使用率会达到约30%,而不使用模糊时仅达到约6%。为什么?

详情:

我在页面中有一组随机生成的项目,这些项目具有CSS动画(在CSS文件中)和随机生成的宽度、高度以及重要的是内联应用的模糊值。

CSS文件样式如下:

animation-name: rise;
animation-fill-mode: forwards;
animation-timing-function: linear;
animation-iteration-count: 1;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
-webkit-transform: translate3d(0,0,0);

transform: translateZ(0);

通过style属性,可以在行内应用宽度、高度和模糊效果。

<div class="foo" style="width:99px;height:99px;
                        filter:blur(2px);
                        -webkit-filter:blur(2px) opacity(0.918866247870028);
                        -moz-filter:blur(2px) opacity(0.918866247870028);
                        -o-filter:blur(2px) opacity(0.918866247870028);
                        -ms-filter:blur(2px) opacity(0.918866247870028);"></div>

启用模糊效果后,我的CPU使用率约为30%。当我禁用模糊时,CPU使用率降至约6%。
这是怎么回事?Chrome只能在没有应用模糊的情况下进行GPU加速吗?如果是这样,为什么?
更新1:
动画“rise”的外观如下:
@keyframes rise {
    0% {
        transform: translateY(0px);
    }
    100% {
        transform: translateY(-1000px);
    }
}

无关紧要,但是您在 filter:blur(2)px 中有个拼写错误。 - Chris
好眼力 Chris。谢谢。 - Jamie Dixon
2
我感到惊讶。当使用模糊效果时,我会预期高CPU使用率而不是硬件加速。模糊操作是一种昂贵的操作。你有检查过在渲染选项下show layer borders设置开启GPU吗? - Colin Bacon
@ColinBacon 我在页面上的一个元素周围得到了一个芥末色边框,但是动画元件有一个蓝色边框。这是否重要? - Jamie Dixon
基本上,创建模糊效果是一个处理器密集型的操作,特别是在动画中。如果您的硬件可以与图形加速器一起多任务处理,这会有所帮助,但仍然需要大量的内存读写。 - Arif Burhan
显示剩余8条评论
2个回答

3
我认为模糊效果并不是导致你问题的原因,它只是使问题比以前更加明显。问题在于你的动画中的 transform: translateY 覆盖了你用于强制 GPU 加速的 transform: translateZ(0)
这是你现在运行的代码的时间线记录,注意主线程和光栅化线程上的所有活动:

enter image description here

现在将其与应用了will-change: transform.foo的录音进行比较:

enter image description here

主要和光栅上没有任何活动。

应用此修复程序有两个步骤:

  1. will-change: transform应用于.foo。这会让浏览器知道您打算更改该属性并将其呈现在GPU上,以便进行相应的处理。

  2. 目前Edge和IE没有支持will-change。因此,在动画中使用transform: translate3d(0, -1000px, 0);来强制进行GPU加速。请注意,这是一个hack,因此我们将检测will-change的支持,并在支持它的浏览器中使用transform: translateY

最终代码:

@keyframes rise {
    0% {
        transform: translate3d(0, 0, 0);
    }
    100% {
        transform: translate3d(0, 1000px, 0);
  }
}

@supports (will-change: transform) {
  @keyframes rise {
      0% {
          transform: translateY(0px);
      }
      100% {
          transform: translateY(1000px);
    }
  }
}

div {
  width: 100px;
  height: 100px;
  background: #f00;
  animation: rise forwards 2s linear infinite;
  will-change: transform;
}

这里有一个可用的版本:http://jsbin.com/mosuvikoto/edit?html,css,output

-2

不要在内联样式中模糊它。将模糊效果放入样式文件中。


2
这会如何帮助解决我的问题? - Jamie Dixon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接