Vintage racers Chrome FPS counter

Devices that support CSS 3D transforms process them through the GPU, a specialized computer sub-component dedicated to intensive pixel manipulation. GPU processing is commonly involved in games, native apps and 3D animations, but not for 2D transforms on web pages. Current browsers fall back on using the CPU for 2D animation, trading efficiency for raw power. This can visibly affect the smoothness and fluidity of CSS animations on all platforms, especially mobile.

We can, with a little trickery, pipeline ordinary 2D CSS animations through the GPU to create a smoother result. As an example, let’s look at moving a clipped image inside a container on hover:

div#vintage-racers {
	width: 33%; 
	position: relative; 
	overflow: hidden; 
	border: 2px solid #000; 
	font-size: 0; 
	height: 300px;
}
div#vintage-racers img {
	position: absolute;
	left: 0;
	transition: 1s all ease-in-out;
}
div#vintage-racers:hover img {
	left: -100%;
}
Vintage racers

While the animation works when you move your mouse over the div, you may see a little hesitation and jerkiness in the result. To make the animation smoother, we can add a . The trick is to write the transform in such a way that it won’t alter the visual appearance of the element itself; we simply want to include the transform to open the path to the GPU, which will enable the 2D transition to stream through with it:

div#vintage-racers img { 
	position: absolute;
	left: 0;
	transition: 1s left ease-in-out;
	transform: translate3d(0,0,0);
}

(Remember that you’ll need to include vendor prefixes for most browsers; note that I’ve also changed the transition property from all to left to further increase the performance of the animation; arguably, using a 2D translate function rather than relative positioning to move the image would be even more efficient).

Vintage racers

The result looks like this:

Depending on the power of your device or computer, you should see that the second transition is significantly smoother than the first. If you need reassurance that the GPU is in fact being accessed, Chrome has a neat method of measuring the performance of your animation:

  1. In Chrome’s URL bar, type about:flags
  2. Find the preference titled “FPS Counter” and click the Enabled link immediately underneath it.
  3. Go to the bottom of the window and click Relaunch Now

The FPS counter shows the number of frames per second in the browser, and is only shown if the GPU is engaged during the page render. Try removing the 3D transform to see the difference.

While this technique will likely benefit small CSS animations on mobile devices, it should be noted that it is possible to overwhelm the relatively tiny VRAM of smartphones and tablets using the method. Testing is important; if you find that the technique benefits desktop browsers but overloads mobile platforms, you might try turning the effect off in the latter via an @media query:

@media only screen and (max-device-width: 1024px) {
	div#vintage-racers img {
		transform: none;
	}
}

Photograph provided by Charles Seguy, licensed under Creative Commons.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.