Chrome 每帧解码大图

Chrome decodes large image every frame

我正在尝试制作一些交互式地图,其中我使用了两个非常大的图像(3200x800 和 4096x1024 像素)。问题是,Chrome 解码每一帧都有云的图像……所以性能真的很差(片段中的示例)。

发现了类似的问题 here,但没有帮助。我在 Linux Mint 17.1(64 位)上使用 Chrome 43(64 位)。我也试过 Firefox 没问题...

html, body {
  height: 100%;
}

body {
  margin: 0;
  overflow: hidden;
}

div {
  position: absolute;
  width: 3200px;
  height: 1800px;
  background: url('http://i.imgur.com/p1Jf722.png'), url('http://i.imgur.com/zUkgN3j.jpg');
  animation: clouds 200s linear infinite;
  transition: 5s;
  left: 0;
  top: 0;
}

@keyframes clouds {
  from { background-position: 0 0, left top; }
  to { background-position: 4096px 0, left top; }
}

body:hover > div {
  left: -500px;
  top: -250px;
}
<div></div>

这里可能有多种方法可以提高性能,但最简单的方法就是通过向您的 div 添加非失真变换,将所有内容卸载到 GPU 上。瞧,没有更多的图像解码。

html, body {
  height: 100%;
}

body {
  margin: 0;
  overflow: hidden;
}

div {
  position: absolute;
  width: 3200px;
  height: 1800px;
  background: url('http://i.imgur.com/p1Jf722.png'), url('http://i.imgur.com/zUkgN3j.jpg');
  animation: clouds 200s linear infinite;
  transition: 5s;
  left: 0;
  top: 0;
  transform: translateZ(0);
}

@keyframes clouds {
  from { background-position: 0 0, left top; }
  to { background-position: 4096px 0, left top; }
}

body:hover > div {
  left: -500px;
  top: -250px;
}
<div></div>

使用伪元素和transform还是用了很多CPU,但是比较流畅。而且完全杜绝了图片解码。

我认为 Chrome 正在为 div 背景使用单个缓冲区。当您更改此缓冲区中 2 个图像的相对位置时,它会变得无效并且必须重新解码。可能FF可以为每张图片分配一个中间缓冲区,即使在相同的背景下使用

html, body {
  height: 100%;
}

body {
  margin: 0;
  overflow: hidden;
}

div {
  position: absolute;
  width: 3200px;
  height: 1800px;
  background: url('http://i.imgur.com/zUkgN3j.jpg');
  transition: 5s;
  left: 0;
  top: 0;
  background-position: left top;
  transform: translateZ(0px);
}

div:after {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  background: url('http://i.imgur.com/p1Jf722.png');
  animation: clouds 200s linear infinite;
  transition: 5s;
  left: 0;
  top: 0;
  transform: translateZ(0px);
}


@keyframes clouds {
  from { background-position: 0 0; }
  to { background-position: 4096px 0; }
}

body:hover > div {
  left: -500px;
  top: -250px;
}
<div></div>