Using pseudo-element and conversion still uses a lot of CPU, but it is pretty smooth. And this absolutely eliminates image decoding.
I think Chrome uses one buffer for the background div. When you change the relative positions of two images in these buffers, it becomes invalid and must be re-decoded. FF can probably allocate an intermediate buffer for each image, even if it is 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>
source share