During the last few weeks we were busy helping developers to convert their HTML5 apps from platforms like WebOS and ChromeOS to FirefoxOS and the target hardware this operation system is right now aiming for. As these are slow mobiles, we found that quite some tweaking had to be done. The reason was in most cases libraries using outdated ways to animate and position things on the screen. These old ways of working are needed to support legacy browsers and in a lot of cases are not needed as these legacy browsers will never see the apps in the first place.
Aside: I will cover a lot of this in my keynote at the jQuery Europe conference called “Helping or hurting?”.
Tip 1: Use CSS animations/transitions
Instead of using your library’s
Tip 2: Use
requestAnimationFrame() instead of
This has been explained many times – a
setInterval() call runs code at an assumed frames per second speed that may or may not be possible. It tells the browser to render results even whilst the browser is currently not drawing as the video hardware is not in the next display cycle. On the other hand,
requestAnimationFrame() will wait till the browser is ready and only send your changes when they will result in a visual display. Another great side-effect for using rAF is that animations don’t happen when the tab is inactive – that way your app is not responsible for hammering the CPU/GPU and sucking battery whilst it doesn’t do anything for the end user.
Tip 3: Use CSS transforms instead of
position: absolute and top/left
Again the reason is hardware acceleration. CSS transforms using
translate(x, y) run on the GPU whereas positioning absolutely and using top and left hammer the main processor. This is worsened by not rounding your pixel positioning. Using transforms also means that you have a much bigger arsenal at your proposal. Rotation and 3D transformations just mean adding to the transform string. With top/left you need to calculate them yourself and mess around with depth of field. Paul Irish has an in-depth analysis of the benefits of
translate() from a performance point of view. In general, however, you have the same benefits you get from using CSS animations: you use the right tool for the job and leave the optimisation to the browser. You also use an easily extensible way of positioning elements – something that needs a lot of extra code if you simulate translation with top and left positioning. Another benefit is that the technique is the same in Canvas.
Tip 4: Make events immediate
As old-school, accessibility aware web developers we love click events as they also come with the added benefit of supporting keyboard input. On mobile devices these are too slow though and you should use
touchend instead. The reason is that these don’t have a delay that makes the interaction with the app appear sluggish. If you test for touch support first, you don’t sacrifice accessibility either. The Financial Times use a library called fastclick for that purpose, which is available for you to use.
Tip 5: Keep it simple and re-use as much as you can
One big performance issue we found in HTML5 apps was that moving lots of DOM elements around makes everything sluggish – especially when they feature lots of gradients and drop shadows. Simplyfying your look and feel and moving a proxy element around when you drag and drop helps a lot.
(Includes videos and all)
- Jake Archibald’s Snow in Canvas Land shows how he sped up some old code by switching to
requestAnimationFrame()and re-using objects instead of constantly creating new ones
- James Long: Making (good) webapps – some Firefox OS specific things, but good overall tips
- Why moving elements with
translate()is better than pos:abs top/left is Paul Irish’s in-depth analysis of the differences
- Patrick Lauke’s German article on touch events (use Google translate – the code and the demos are the important bits)
- Video of James Long’s Writing Firefox OS HTML5 Apps using Mortar talk
- A great collection of App performance articles by Paul Lewis
View full post on Christian Heilmann