7

I'm trying to do some interactive map, where I'm using two very large images (3200x800 and 4096x1024 pixels). Problem is, that Chrome decode image with clouds every frame... so performance is really poor (example in snippet).

enter image description here

Found similar problem here, but didn't help. I'm using Chrome 43 (64-bit) on Linux Mint 17.1 (64-bit). I also tried Firefox and without problem...

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>
Community
  • 1
  • 1
Matěj Pokorný
  • 16,977
  • 5
  • 39
  • 48

2 Answers2

2

Using a pseudo element and transform still uses a lot of CPU, but it is quite smoother. And it absolutely eliminates the image decodes.

I think that Chrome is using a single buffer for a div background. When you change the relative positions of the 2 images in this buffers, it becomes invalid and has to be rendered decoded again. Probably FF can allocate an intermediate buffer for every image, even if used in the same background

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>
vals
  • 61,425
  • 11
  • 89
  • 138
0

There are probably multiple ways to do improve performance here, but the lowest hanging fruit is just to offload everything onto the GPU by adding a non-distorting transform to your div. Voila, no more image decodes.

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>
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • Thanks for advice, but [didn't help](http://i.imgur.com/KGSpNkE.png). Looks like Chrome still use only CPU (2 cores with 4 threads. All on 50%. Firefox runs without any CPU work). – Matěj Pokorný May 25 '15 at 16:49