Search code examples
jqueryperformancejquery-uiipadjquery-events

Mobile Safari (iPad) scrolling performance when binding 'touchstart' to document


I've been investigating some performance issues with scrolling my website on iPad Safari. We have some pages which are large table elements with up to 500 rows; the performance impact definitely seems related to the number of rows in the table (and, on pages without such tables, scrolling performance seems fine). Desktop browsers are perfectly fine.

You can try this out at the following link. NOTE: to repro, make sure to change the default of 25/page to 500/page. http://www.cellartracker.com/list.asp?table=Notes&iUserOverride=0&T=1000

After doing quite a bit of debugging, I've found that if I remove any 'touchstart' events I've bound, scrolling performance is normal (and super-fast, as expected). I have a few $(document).on('touchstart', '<selector>', function ()...) events configured to assist with making some hover functionality accessible to touch devices. Currently, I bind to $(document) for two reasons:

  1. There can be a lot of elements that match the selector, so traditionally the performance of a single delegated event handler is better than 500+ handlers attached to each element (I just fixed some perf issues related to this on IE8).
  2. Some of the affected elements are loaded via AJAX, so those wouldn't automatically get the handler if I bound to the individual elements.

OK, great--I've found the cause--but I don't know why this is a problem only on pages with large tables and how to work around it. For devices with BOTH touch and keyboard/mouse, I want each input mechanism to act consistently (so the if (touch) bind('click') else bind('mouseenter') approach isn't what I'm looking for). Plus, I'm also looking at implementing the Fast Buttons approach for some elements, which would likely necessitate binding to $(document) as that's where the corresponding click handlers currently are bound.

So...any ideas on how to improve scrolling perf on these pages while still binding touchstart to $(document)? The HTML is pretty fixed at this point, but if there are simple tweaks to the DOM that would have a big impact I'm open to it.


Solution

  • Well, after putting this aside for a few days to work on something else, I came back to find the performance has mysteriously improved significantly! Tracing back the other changes that were made, I found the root of the performance issue: jQuery UI 1.8.20. I just upgraded to jQuery UI 1.9.2 to fix some other issues, and now I am no longer seeing the horrible scroll lag/perf issues.

    Now, I still do see a slight perf degradation from having touchstart bound to $(document), but now it's so minor it's fairly imperceptible. If anyone has other guidance on how to better optimize the original question, though, I'd still love to hear it!