Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome decodes large image every frame

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>
like image 659
Matěj Pokorný Avatar asked May 23 '15 14:05

Matěj Pokorný


1 Answers

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>
like image 94
vals Avatar answered Oct 05 '22 16:10

vals