微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

改善CSS3背景位置动画的性能

我正在尝试改进 CSS3动画,因为当前的代码似乎导致了一些过多的cpu负载,并且浏览器似乎有些滞后.

我能做什么?我有所有的供应商前缀等.我不确定我可以改进代码或重构它以使用它作为最佳代码实践.

Fiddle Demo

.wrapper {
  width: 960px;
  height: 140px;
  margin-top: 80px;
  position: relative;
}
.content:before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-transform-origin: 50% 50% 0;
  -ms-transform-origin: 50% 50% 0;
  transform-origin: 50% 50% 0;
  v -webkit-animation-name: sideupscroll;
  animation-name: sideupscroll;
  /*animation-duration*/
  -webkit-animation-duration: 80s;
  animation-duration: 80s;
  /*animation-timing-function*/
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  /*animation-iteration-count*/
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  background: url("http://i.imgur.com/wNna7D3.png") repeat fixed 0 0 indigo;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
/* Safari and Chrome */
@-webkit-keyframes sideupscroll {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: -50% -100%;
  }
  100% {
    background-position: -100% -200%;
  }
}
@keyframes sideupscroll {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: -50% -100%;
  }
  100% {
    background-position: -100% -200%;
  }
}
<div class="wrapper">
  <div class="content"></div>
</div>

解决方法

原因

动画元素的背景位置始终是资源密集型的,并且几乎在所有浏览器中都很可能导致延迟动画.这是因为,对背景位置的更改会导致在所有浏览器中重新绘制一个合成(它还会导致在Webkit中重新布局).由于需要执行如此多的昂贵操作,因此结果始终是滞后的.

有问题的片段:

以下代码段与您的小提琴相同(没有供应商前缀).启用“Show Paint Rects”选项后,运行此代码段并使用Chrome Dev工具进行检查.您会在元素顶部看到一个红色或绿色的颜色框(这是画颜料矩形),并且该框将持续闪烁或在整个动画期间保持颜色.它表明经常发生重绘,因此会影响性能.

在Firefox中,可以通过在about:config页面中启用nglayout.debug.paint_flashing来看到paint rects(将其设置为true).

.wrapper {
  width: 960px;
  height: 140px;
  margin-top: 80px;
  position: relative;
}
.content:before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  transform: translateZ(0);
  transform-origin: 50% 50% 0;
  animation-name: sideupscroll;
  animation-duration: 80s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  background: url("http://i.imgur.com/wNna7D3.png") repeat fixed 0 0 indigo;
  animation-fill-mode: both;
}
@keyframes sideupscroll {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: -50% -100%;
  }
  100% {
    background-position: -100% -200%;
  }
}
<div class="wrapper">
  <div class="content"></div>
</div>

最好避免动画background- *属性(所有这些属性都是可视属性)并使用像transform这样的属性.使用变换在Blink(Chrome)和EdgeHTML中至少可以产生更好的性能,因为Blink只进行重新组合,而EdgeHTML仅首次触发重新布局(动画中的第一次更新).

没有问题的片段:(或者至少对Blink和EdgeHTML中的性能影响小得多)

下面的代码片段使用transform属性(translateX和translateY)来实现与预期输出非常相似的内容(但不一样).如果使用开发工具检查此片段,您会看到绿色框(绘制矩形)仅在动画开始时出现一次.发布,浏览器只执行合成,因此性能要好得多.

.wrapper {
  width: 960px;
  height: 140px;
  margin-top: 80px;
  position: relative;
  overflow: hidden;
}
.content:before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  width: 200%;
  height: 400%;
  content: "";
  background: url("http://i.imgur.com/wNna7D3.png") 0 0 indigo;
  background-repeat: repeat;
}
.content {
  position: relative;
  height: 100%;
  width: 100%;
  animation-name: sideupscroll;
  animation-duration: 80s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-fill-mode: both;
}
@keyframes sideupscroll {
  0% {
    transform: translateX(0%) translateY(0%);
  }
  50% {
    transform: translateX(-50%) translateY(-100%);
  }
  100% {
    transform: translateX(-100%) translateY(-200%);
  }
}
<div class="wrapper">
  <div class="content"></div>
</div>

Gecko和Webkit怎么样?

不幸的是,在撰写本文时,对于使用这些渲染引擎的浏览器来说,没有解决方案.唯一的选择似乎是减少动画持续时间.动画持续时间的减少意味着没有.重新绘制重新布局所需的重新组合周期较小,因此动画的表现更好.

下面的代码片段在Firefox中看起来不那么滞后,因为持续时间只有20秒.

.wrapper {
  width: 960px;
  height: 140px;
  margin-top: 80px;
  position: relative;
  overflow: hidden;
}
.content:before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  width: 200%;
  height: 400%;
  content: "";
  background: url("http://i.imgur.com/wNna7D3.png") 0 0 indigo;
  background-repeat: repeat;
}
.content {
  position: relative;
  height: 100%;
  width: 100%;
  animation-name: sideupscroll;
  animation-duration: 20s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-fill-mode: both;
}
@keyframes sideupscroll {
  0% {
    transform: translateX(0%) translateY(0%);
  }
  50% {
    transform: translateX(-50%) translateY(-100%);
  }
  100% {
    transform: translateX(-100%) translateY(-200%);
  }
}
<div class="wrapper">
  <div class="content"></div>
</div>

有用的链接

> CSS Triggers – 列出哪些属性导致触发的操作.
> HTML5 Rocks – Accelerated Rendering in Chrome – 介绍加速渲染在Chrome中的工作原理(以及如何启用“Show Paint Rects”选项)

Note: As I had already stated above,the animation is not 100% the same as what you had in question but in my opinion this is about the closest you Could get.

原文地址:https://www.jb51.cc/css/216021.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。