Speeding up HW Accordion

I tend to make a lot of use of PhoneGap – it’s great for getting an iPhone / iPad project (that isn’t too complex) up and running quickly, either for prototyping or even for final releases.  However, there’s some shortcomings, one of which is PhoneGap makes use of MobileSafari, which has it’s own little freaky problems.

One of those problems is getting things to scroll nice and smoothly.  For that I discovered Matteo Spinelli’s iScroll, and with that, his other excellent piece of work, HW Accelerated Accordion.

Unfortunately, I found a project the Accordion harfs on a bit – my upcoming project has a section that’s an accordion with quite a few elements, and a LOT of formatting and div’s insides those elements.  It was bad enough it took over four seconds for the page to load on an iPad!

So I dug into his library to do a little optimizing – I posed the results on his page, but am also posting them on here for those googling for a solution 🙂

This, BTW, is for version 1.0 of HW Accordion and 3.7.1 of iScroll – your milage may vary if you’re using other versions!

So, part 1 is for people who are supporting iOS and Android (part 2 breaks Android), particularly when using PhoneGap.

First, in accordion.js, comment out:

/*	that.wrappers[i].style.webkitTransitionProperty = ‘-webkit-transform’;

that.wrappers[i].style.webkitTransitionTimingFunction = ‘cubic-bezier(0,0,0.25,1)’;

that.wrappers[i].style.webkitTransitionDuration = ’0′; */ (lines 35 – 37)


 /* accordions[i].style.webkitTransitionProperty = ‘-webkit-transform’;

accordions[i].style.webkitTransitionTimingFunction = ‘cubic-bezier(0,0,0.25,1)’;

accordions[i].style.webkitTransitionDuration = ’0′; */

In your CSS under #accordian > div add:

-webkit-transition-property: -webkit-transform;

-webkit-transform-duration: 0;

-webkit-Transition-Timing-Function: cubic-bezier(0,0,0.25,1);

and under #accordion > div > div:last-child add the same bit.

You won’t get a HUGE speed burst, but you’ll get a bit extra out of it – it’s 6 extra style assignments in the javascript that doesn’t have to happen (everybit counts). This reduced my load time from about 4 seconds to just over 2 seconds.

Now, if you’re not worried about Android, or can do separate compiles for iOS and other platforms (for instance, using PhoneGap rather than loading from a website, or if you can do platform dependent includes), then there’s a second speed boost you can pull off that’s more significant.

And I’ll make sure this is clear:  THIS ONLY WORKS ON iOS AND BREAKS ANY NON-3D ACCELERATED WEBKIT PLATFORM. (There, that made me feel better. 😉

First, do everything that’s described in part 1. Then…

In accordion.js comment out:

//	accordions = document.querySelectorAll(‘#’ + el + ‘ > div > div:last-child’); (Line 30)

 //	that.wrappers[i].style.webkitTransform = translateOpen + ’0,0′ + translateClose; (line 38)

/* for (i=0, l=accordions.length; i div and #accordion > div > div:last-child
 accordions[i].style.webkitTransitionProperty = '-webkit-transform';
 accordions[i].style.webkitTransitionTimingFunction = 'cubic-bezier(0,0,0.25,1)';
 accordions[i].style.webkitTransitionDuration = '0';
 accordions[i].style.webkitTransform = translateOpen + '0,0' + translateClose;
} (lines 49 - 54)

Then, in your CSS add:

-webkit-transform = translate3d(0,0,0);

to both #accordion > div and #accordion > div > div:last-child.

Now load time for my complex page goes from just over 2 seconds to instant.

The translate3d bit is what breaks Android – no 3d transform for the webkit version. Sorry. However, if you’re compiling using PhoneGap or similar, you can always make two CSS files and just include the right one in each project, and use the non-3D transform for other platforms besides iOS.

Hope that helps anyone who’s ran into some slowdown before!

Leave a Comment