Home » Tutorials » HTML & CSS » Replacing jQuery Animation With CSS Hardware Accelerated

Replacing jQuery Animation With CSS Hardware Accelerated

Replacing jQuery Animation With CSS Hardware Accelerated

  • Stumble it!
  • Share

“Mobile Web Is Too Slow!”

As a mobile web developer, I get asked on why mobile native app offer the smoothest UI transition than web app? Why native app has most feature-rich user experience than mobile web app? So should we all pack our mobile web app work and go native? Well, the answer is no.

How Do We get Smoother User Experiences in Web App?

Most smartphones these days have GPU (Graphic Processing Unit) that suitable for hardware acceleration. Native applications have direct access to the GPU, because of this they offer better user experiences than web app. So, we can leverage the GPU powers by offloading some heavy tasks (transition / animation) to the GPU for better performance in browser.

We’ll discuss the techniques here,: replacing JQuery animation / transition with CSS Hardware Accelerated transition.

Replace jQuery Animation With CSS Hardware Accelerated

jQuery animations, transition are not GPU accelerated, so we need to convert it to CSS first. But please be noted that currently browsers will not automatically offload our converted CSS to GPU, instead execute the code from browser’s slower rendering engine. So what exactly forces the browser to offload animation / transition to GPU?

The answer is enable 3D rendering. Even though we’re not animating our element in 3D, but by enabling 3D rendering, we can force browser to swap to GPU acceleration mode.

Ok, let’s start to convert jQuery animation to CSS Hardware Accelerated. Let’s take a look on the example code of jQuery accordion:

<div class="list_button">
	<ul>
		<li class="parent"><a href="#">Rate the App &#8675;</a>
			<ul class="children">
				<li><a href="#">1 Star</a></li>
				<li><a href="#">2 Stars</a></li>
				<li><a href="#">3 Stars</a></li>
				<li><a href="#">4 Stars</a></li>
				<li><a href="#">5 Stars</a></li>
			</ul>
		</li>
	</ul>
</div><!-- END list_button -->


<script>
 $('.parent a').bind('touchstart click', function(e) {
	e.preventDefault();
	$(this).siblings('.children').slideToggle(500);
}); 
</script>

As you can see, traditionally we use jQuery toggleSlide() method to toggle slide up & slide down for the selected accordion, and now let’s see the following example on how are we going to replace the toggleSlide() method with CSS hardware accelerated code.

Enable CSS Hardware Accelerated

For best practice, we should always only enable hardware acceleration for supported browser, so we need the following JavaScript to check and enable hardware acceleration for us:

<script>
var thisBody = document.body || document.documentElement,
	thisStyle = thisBody.style,
	transitionEndEvent = 'webkitTransitionEnd transitionend',
	cssTransitionsSupported = thisStyle.WebkitTransition !== undefined || thisStyle.transition !== undefined,
	has3D = ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix());


// Switch to CSS3 Transform 3D if supported & accordion element exist
if(cssTransitionsSupported && has3D ) {
	if($('.children').length > 0) { 
		$('.children').addClass("accordion_css3_support");
	}
}


 $('.parent a').bind('touchstart click', function(e) {
	e.preventDefault();
	//If browser not support transition or 3D transform (for webkit browser only)
	if(!cssTransitionsSupported || !has3D ) {
		$(this).siblings('.children').slideToggle(500);
	} else {
		$(this).siblings('.children').toggleClass("animated");
	}
}); 

Define Hardware Accelerated CSS Style

We already done the logic part on Javascript side, now it’s time to define the CSS that trigger the browser to offload animation to GPU.

.accordion_css3_support {
	display: block;
	max-height: 0;
	overflow: hidden;
	-webkit-transform: translate3d(0,0,0);
	-webkit-transition: all 0.5s linear;
	transform: translate3d(0,0,0);
	transition: all 0.5s linear;
	-webkit-backface-visibility:hidden;
	-webkit-perspective: 1000;
}

.children.animated {
	max-height: 1000px;
	-webkit-transform: translate3d(0,0,0);
	transform: translate3d(0,0,0);
}

The declaration of transform: translate3d(0,0,0) triggers GPU acceleration in mobile browser. In Chrome and Safari we might see a flickering effect when using CSS transforms, so we need the declaration of -webkit-backface-visibility:hidden; & -webkit-perspective: 1000; to fix the issue.

Final Code

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Demo: Replacing jQuery Animation With CSS Hardware Accelerated | onlyWebPro.com</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no, maximum-scale=1.0, minimum-scale=1.0" />
<meta name="description" content="Web Development Tutorial Replacing  jQuery Animation With CSS Hardware Accelerated for mobile web">
<meta name="keywords" content="CSS, Hardware Accelerated, jQuery, Animation, CSS Animation, jQuery Animation, Mobile, iOS, Mobile Web" />
<link href='http://fonts.googleapis.com/css?family=Roboto+Slab:400,700' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Roboto:400,700' rel='stylesheet' type='text/css'>
<style>
body {
	background: #3DA938;
	color: #2d762a;
	font-family: 'Roboto', Arial, Helvetica, sans-serif;
	font-size: 14px;
}

h1 {
	color: #2d762a;
	font-family: 'Roboto Slab', Arial, Helvetica, serif;
	font-size: 24px;
}

a {
	color: #fff;
	text-decoration: none;
}

.info {
	margin-bottom: 30px;
}

.site_wrapper {
	margin: 0 auto;
	padding: 15px 15%;
}

.list_button {
	background: #fff;
	border-radius: 4px;
}

.list_button ul {
	list-style-type: none;
	padding: 0;
}

.list_button a:first-child {
	border-top: none;
}

.list_button a {
	border-top: 1px solid #eee;
	color: #2d762a;
	display: block;
	font-weight: bold;
	padding: 15px 20px;
	text-decoration: none;
}

.children {
	display: none;
}

.accordion_css3_support {
	display: block;
	max-height: 0;
	overflow: hidden;
	-webkit-transform: translate3d(0,0,0);
	-webkit-transition: all 0.5s linear;
	transform: translate3d(0,0,0);
	transition: all 0.5s linear;
	-webkit-backface-visibility:hidden;
	-webkit-perspective: 1000;
}

.children.animated {
	max-height: 1000px;
	-webkit-transform: translate3d(0,0,0);
	transform: translate3d(0,0,0);
}
</style>
</head>
<body>
	
<div class="site_wrapper">
	<div class="info">
		<h1>Demo: Replacing jQuery Animation With CSS Hardware Accelerated</h1>
		<p>Most smartphones these days have GPU (Graphic Processing Unit) that suitable for hardware acceleration. Following is the example of the accordion using CSS hardware accelerated.<br />
		<br /> *this example is only works in webkit browser such as Safari &amp; Chrome.
		</p>
		<p>Click here to continue reading the tutorial - <a href="http://www.onlywebpro.com/2014/05/01/replacing-jquery-animation-with-css-hardware-accelerated/" target="_blank"><strong>Replacing jQuery Animation With CSS Hardware Accelerated</strong></a></p>
	</div>
	
	<div class="list_button">
		<ul>
			<li class="parent"><a href="#">Rate the App &#8675;</a>
				<ul class="children">
					<li><a href="#">1 Star</a></li>
					<li><a href="#">2 Stars</a></li>
					<li><a href="#">3 Stars</a></li>
					<li><a href="#">4 Stars</a></li>
					<li><a href="#">5 Stars</a></li>
				</ul>
			</li>
		</ul>
	</div><!-- END list_button -->

	<div class="list_button">
		<ul>
			<li class="parent"><a href="#">Rate the App &#8675;</a>
				<ul class="children">
					<li><a href="#">1 Star</a></li>
					<li><a href="#">2 Stars</a></li>
					<li><a href="#">3 Stars</a></li>
					<li><a href="#">4 Stars</a></li>
					<li><a href="#">5 Stars</a></li>
				</ul>
			</li>
		</ul>
	</div><!-- END list_button -->

	<div class="list_button">
		<ul>
			<li class="parent"><a href="#">Rate the App &#8675;</a>
				<ul class="children">
					<li><a href="#">1 Star</a></li>
					<li><a href="#">2 Stars</a></li>
					<li><a href="#">3 Stars</a></li>
					<li><a href="#">4 Stars</a></li>
					<li><a href="#">5 Stars</a></li>
				</ul>
			</li>
		</ul>
	</div><!-- END list_button -->
</div>


 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var thisBody = document.body || document.documentElement,
	thisStyle = thisBody.style,
	transitionEndEvent = 'webkitTransitionEnd transitionend',
	cssTransitionsSupported = thisStyle.WebkitTransition !== undefined || thisStyle.transition !== undefined,
	has3D = ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix());


// Switch to CSS3 Transform 3D if supported & accordion element exist
if(cssTransitionsSupported && has3D ) {
	if($('.children').length > 0) { 
		$('.children').addClass("accordion_css3_support");
	}
}


 $('.parent a').bind('touchstart click', function(e) {
	e.preventDefault();
	//If browser not support transition or 3D transform (for webkit browser only)
	if(!cssTransitionsSupported || !has3D ) {
		$(this).siblings('.children').slideToggle(500);
	} else {
		$(this).siblings('.children').toggleClass("animated");
	}
}); 


</script>
</body>
</html>

In order to experience the result of before and after enabled GPU hardware acceleration, you can view the following demo using different browsers in your mobile device:

  • Android native browser, iOS Safari & Chrome (Hardware Accelerated Enabled in this example);
  • Firefox mobile (Non Hardware Accelerated Enabled in this exmaple)

QR code to CSS Hardware Accelerated Demo

View Demo

Conclusion

By leveraging CSS Hardware Accelerated correctly, can lead to smoother user experience of your web app. Be careful with these method, and only use them to the piece of element that you experience a true performance problem. Using the GPU unnecessarily can cause significant performance issues because it increases memory use –– it will also affect the battery life on mobile devices.

Please note that example that we mentioned above might only works on some of the Webkit powered browsers such as Safari & Chrome.


  • Launch Native iOS Google Maps Via Your Web App
  • Speed Up Page Loads Time Using Prefetch / Prerender
  • Testing & Troubleshooting Retina Display Content Without Actual Device

  • Twoopl

    CSS animation is one of the best, take a look here http://designmodo.com/backface-visibility-css-animation/

  • john

    not sure why more people arent doing this…jquery mobile essential is this with training wheels, but i feel like its not well explained….or use case specific…or…bloated, even with customizing…

Android, iOS Development Tutorials