Improve rendering performance with CSS3 enabled hardware acceleration
Web apps are more often than before used on mobile devices, and thus their performance compared to native apps. Some believe that web apps, or hybrid apps, never can have as fast and fluid graphical interfaces as native apps. Luckily there are some nifty tricks out there to help us get closer!
Hardware acceleration
The key to a native experience might be to enable hardware acceleration of some of the sluggish elements in your app. "Enable?" you say, "How come hardware acceleration isn't always on??". Good question! But there are reasons. Most elements does not require acceleration, and enabling hardware acceleration is costly, especially for devices with limited batteries. Most of the time the browser knows best when to use acceleration, and when to not. So we have to specifically enable it when we disagree.
How to accelerate
The browser can hardware accelerate CSS property transitions on elements that have their own compositing layer. Each browser has its own rules for when an element gets such a layer, but it is possible to force its hand by applying a CSS property that requires a compositing layer to the element. Preferably without changing the appearance of the element.
A simple implementation
The simplest implementation i can think of is creating a CSS class that can be added to elements that needs hardware acceleration:
CSS:
.hardware-accelerated {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
HTML:
<ul class="hardware-accelerated">
<li>Complex stuff like an <img /></li>
...
</ul>
Useful applications
I find that when working with complex lists with images and multiple layers of elements, gradients and so on, hardware acceleration can have a huge impact on the rendering performance on devices.
Typically you get some sort of flickering when swiping or scrolling. In the example below, I am swiping left and right in a horizontal list of TV-program posters. On the left hand side you can see some black areas flickering in the direction I am scrolling. After enabling hardware acceleration you can see that this is completely gone.
Testing without hardware acceleration | Testing with hardware acceleration |
---|---|
![](/content/images/2015/10/demo_without_hw-2.gif) | ![](/content/images/2015/10/demo_with_hw.gif) |
Testing the effect of acceleration
In the example above we could identify the flickering problem fairly easily, but testing the effect of hardware acceleration is often hard in a browser on your laptop. The sluggish experience you get on some devices are often not visible in your development environment, with or without acceleration.
Instead you need to measure the performance, and Google have created some really nice tools for this in Chrome F12-tools.
The tools are enabled from the "drawer" at the bottom of the F12 tools. To open the "drawer" you need to press the ">_" icon on the top right:
With the drawer open you select the "Rendering" tab, and get the following options:
- Show paint rectangles
- Show composited layer borders
- Show FPS meter
- Enable continous page repainting
- Show potential scroll bottlenecks
My favorites are the FPS meter and the scroll bottlenecks. The FPS meter includes two important factors for measuring the impact of hardware acceleration: a graph of FPS, together with the GPU memory consumption. Identifying the scroll bottlenecks helps me find the correct element to enable acceleration of.
It is worth mentioning that none of these options works well together with the F12 tools device mode, so when testing "device sizes" you will have to resize your window to get good results.
In the example below you can see that without hardware acceleration the list is identified with an orange frame with the label "repaints on scroll". When scrolling you can see that the FPS drops down to 10-20, and that hardly any GPU memory are used.
With hardware acceleration enabled you can see that the orange frame disappears. FPS stays around 50, and the GPU memory grows to above 30 MB. Great success!
Testing without hardware acceleration | Testing with hardware acceleration |
---|---|
![](/content/images/2015/10/demo_without_hw_fpsmeter.gif) | ![](/content/images/2015/10/demo_with_hw_fpsmeter.gif) |
Notice that you cannot see any real difference related to the hardware acceleration in the scrolling, but there is a massive difference on some devices.
You are now able to measure it to prove that you are utilizing the GPU!