Using Transforms for Parallax

You really kinda take things for granted as far as technology goes, that is until you start finding the flaws in the way things work. I learned this yesterday as I’m writing some components for an Open Source Storytelling platform built on WordPress. The component I’ve been spending a lot of time on is the parallax component. The general approach to this is by adjusting background position on scroll.

$this.css('background-position', 'center ' + yBgPosition + 'px');

I work on an iMac and I didn’t see any performance issues so I rolled with it; until a colleague on a MBP retina pointed out how choppy it was. It gets hard at this point because on my end I see everything fine, but folks using retina do not. Since I’m a bit OCD about my code and shit has to be perfect, I started researching a better way of doing parallax, and I stumbled across this post by a Flickr engineer on developing the Flickr home page. He talks about using css transforms along with an absolutely positioned div. Taking the div out of the content flow, and utilizing webkits hardware acceleration using transforms dramatically increases parallax performance. So I started to test and apply it to my script.

From this:
$this.css('background-position', 'center ' + yBgPosition + 'px');

To this:
$this.css({'transform':'translate3d(0px,' + yBgPosition + 'px, 0px)'});

So how did it go? We can see the results in the developer console, as new objects are painted and repainted on scroll. This top screenshot shows the painted events with transforms on scroll. The bottom screenshot shows the same thing using bg position. What we’re looking at are those green bars up top.


That is a huge performance increase! So in summary, do not use background position for parallax as it’s pretty taxing and causes issues on retina. Instead use 3d transforms and utilize hardware acceleration. What other tips have you found?