【问题标题】:Css animations - animation is slow and jigglesCss 动画 - 动画缓慢且抖动
【发布时间】:2016-03-22 13:17:15
【问题描述】:

我想问,这段 CSS 代码有什么问题?它用于动画背景图像 - 缩放效果。

@media (min-width: 1000px) {
  .anim-on {
    background-size: 110% 110%;
    background-position: center center;
    animation: shrink 12s infinite alternate;
  }
  .anim-out {
    background-size: 120% 120%;
    background-position: center center;
    animation: small 6s infinite alternate;
  }
  @keyframes shrink {
    0% {
      background-size: 110% 110%;
    }
    100% {
      background-size: 100% 100%;
    }
  }
  @keyframes small {
    0% {
      background-size: 100% 100%;
    }
    100% {
      background-size: 110% 110%;
    }
  }
}

这段代码产生了很好的效果,但我看到,在较慢的机器上,效果很差。

怎么了?或者也许有人有更好的想法,如何以更好的技术创造这种效果?

【问题讨论】:

  • 更改 background-size 会导致重绘,因此会影响性能。
  • 这是一个很好的问题,但它不是属于 Code Review 而不是 SO?
  • @FaustoNA “代码有什么问题”显然与代码审查无关
  • @Heslacher 在这种情况下,性能有问题,我没有发现任何错误。
  • 代码审查是针对与需要改进的工作代码相关的问答进行的,就像这个一样。我并不是说 OP 在这里发布它是不好的,只是想弄清楚。

标签: html css css-transitions css-animations


【解决方案1】:

背景大小是一种视觉属性,因此对其值的任何更改都会导致重新绘制。喷漆是一项非常昂贵的操作,势必会对低端机器的性能产生影响。解决此问题的一种方法是使用 CSS transform(准确地说是缩放)而不是 background-size 更改来生成动画。

会影响性能的代码段:

下面的 sn-p 使用与问题中相同的动画。当您运行此 sn-p 并使用 Chrome 开发工具检查它(通过启用“显示绘制矩形”选项)时,您会看到两个图像都有一个与之关联的绘制矩形(绿色或红色框),并且作为动画正在发生,盒子一直闪烁(或保持原样)。这表明重绘经常发生,因此会影响性能。

.anim-on,
.anim-out {
  height: 200px;
  width: 200px;
  background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on {
  background-size: 110% 110%;
  background-position: center center;
  animation: shrink 12s infinite alternate;
}
.anim-out {
  background-size: 120% 120%;
  background-position: center center;
  animation: small 6s infinite alternate;
}
@keyframes shrink {
  0% {
    background-size: 110% 110%;
  }
  100% {
    background-size: 100% 100%;
  }
}
@keyframes small {
  0% {
    background-size: 100% 100%;
  }
  100% {
    background-size: 110% 110%;
  }
}
/* Just for demo */

div {
  float: left;
  margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>

<div class='anim-on'></div>
<div class='anim-out'></div>

对性能影响较小的代码段:

在下面的 sn-p 中,我将background-image 添加到伪元素,然后对其使用scale 变换以产生放大/缩小效果。父级的overflow: hidden 设置可防止动画影响其大小。如果您使用 Chrome 开发工具对此进行检查,您会看到绿色或红色框仅在页面加载并消失时出现一次。这表明在动画本身期间没有发生进一步的重绘,因此从性能的角度来看它更好。您还会注意到,此动画比之前的动画更流畅。

.anim-on,
.anim-out {
  position: relative;
  height: 200px;
  width: 200px;
  overflow: hidden;
}
.anim-on:after,
.anim-out:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  top: 0px;
  left: 0px;
  background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on:after {
  animation: shrink 12s infinite alternate;
}
.anim-out:after {
  animation: small 6s infinite alternate;
}
@keyframes shrink {
  0% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes small {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(1.1);
  }
}
/* Just for demo */

div {
  float: left;
  margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>

<div class='anim-on'></div>
<div class='anim-out'></div>

您可以在CSS Triggers website 中找到有关各种 CSS 属性以及更改其值将如何影响呈现过程的更多信息。

您可以在以下文章/网站中找到有关渲染过程以及使用transform(相对于少数其他属性)如何提高性能的更多信息:

【讨论】:

  • 感谢您的精彩解释。但我有一个问题:我必须更改 css 文件中的所有背景图像,因为我需要添加 .anim-on:after, .anim-out:after { position: absolute;内容: '';高度:100%;宽度:100%;顶部:0px;左:0px;背景:网址(lorempixel.com/200/200/nature/1); } ?如果是,情况会变得复杂,因为这种动画输入和动画输出声明将不是通用的?
  • 不幸的是,我看不到任何其他更好的选择,因为background-size 动画非常昂贵。如果我找到更好的方法,我会考虑更多并更新答案。我建议您将问题留待一天,希望我们可以获得更好的建议。
  • 只是要注意哈利 - 我会搜索一些更可重用的东西 - 例如只是添加到带有背景图像的 div 一些类以自动动画 - 但我只是想说谢谢你:)跨度>
【解决方案2】:

我编辑了 Henry 代码,现在 css 可以重用,所以用户可以通过 CMS 为元素添加背景图片,其余的由 css 代码完成:

.anim {
 position: relative;
 height: 100vh;
 width: 100%;
 overflow: hidden;
 **background-size: 0px!important;**

}
.anim:after {
position: absolute;
content: '';
 height: 100%;
 width: 100%;
 top: 0px;
 left: 0px;
 background-size: cover !important;
 **background: inherit;**
 z-index: -1;
}
.anim:after {
animation: shrink 12s infinite alternate;
 }
@keyframes shrink {
0% {
transform: scale(1.1);
}
 100% {
transform: scale(1);
}
}
@keyframes small {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}

<section class="anim" style="background: url('images/1.png');"></section>

谢谢 * :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 2017-05-22
    • 1970-01-01
    相关资源
    最近更新 更多