CSS
CSSスプライト

CSSスプライトアニメーションをGPUレンダリングさせる

More than 1 year has passed since last update.

最終的なデモはこちら。
http://jsdo.it/takumifukasawa/QWj9

概要

CSSでスプライト画像の連番アニメーションを実装する場合、background-positionをずらす方法を使っていた。しかし、同じ画面内で、サイズの大きい画像のスプライトアニメーションをいくつも動かしたい場面があり、パフォーマンスがネックになってしまった。

実際、background-positionのcss animationはGPUレンダリングではないので、再描画処理が走ってしまう。chromeのデバッガーツールで、「Rendering」の「Paint Flashing」を見ると、このように再描画処理が走っているのがわかる。

デモはこちら http://jsdo.it/takumifukasawa/8wb2

スクリーンショット 2017-07-30 15.02.15.png

@keyframes sprite-image {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 0 -1064px;
  }
}

.sprite {
  width: 400px;
  height: 266px;
  background-image: url(http://jsrun.it/assets/M/6/J/N/M6JN2.jpg);
  background-size: 400px 1064px;
  animation: sprite-image 1s steps(4) infinite;    
}

css transformを使う

そこで、GPU処理が適用されるcss transformを使った方法を試してみた。before要素に背景画像を当ててanimationさせることで、DOM構造を変えない形にできた。

先ほどと同じようにchromeのデバッガーツールを見てみると、再描画が走っていないことがわかる。これで、background-positionの時よりも負荷を軽減することができた。

デモはこちらhttp://jsdo.it/takumifukasawa/QWj9

スクリーンショット 2017-07-30 15.12.04.png

@keyframes sprite-image {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, -100%);
  }
}

.sprite {
  position: absolute;
  overflow: hidden;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 400px;
  height: 266px;

  &:before {
    content: "";
    display: block;
    width: 400px;
    height: 1064px;
    background-image: url(http://jsrun.it/assets/M/6/J/N/M6JN2.jpg);
    background-size: 400px 1064px;
    animation: sprite-image 1s steps(4) infinite;
  }
}