Question

On Chrome something is seriously wrong with the performance of element.addEventListener("touchstart") in my system, in some cases reaching 100ms for a single call.

r00122 listen touchstart: 60.000ms
r00123 listen touchstart: 61.000ms
r00124 listen touchstart: 61.000ms 

The above is the console.time output of a pure addEventListener call. Identical calls for other events take 0ms. The interesting thing is that every call or two the time taken goes up by another ms. There is no difference when I turn on or off "Emulate touch events".

However, a simple test case on Chrome runs at 0.01ms/call, so there must be some other dependency. I can't think what it is, other than that fact that I have a large number of elements on the page and am setting up many event listeners (1000). But still, in my page on Mozilla and Safari the call is instantaneous. What on earth could be accounting for this?

Was it helpful?

Solution

I'm experiencing the same behaviour inserting listeners to over 1,000 elements, and indeed only in Chrome on desktop. I consider this to be a bug in Chrome, and created the following two-step workaround.

  1. Check if the client supports the touch event; if not, then don't register it. The code I use to check for touch support is based on this answer:

    var bTouchEnabled = 'ontouchstart' in window ||
    ('onmsgesturechange' in window &&
     'msMaxTouchPoints' in window.navigator &&
      window.navigator.msMaxTouchPoints);
    
  2. Don't register all elements at once, but buffer the registering: register 50, call a setTimeout() with a delay of, say, 20 ms, which registers the next 50, repeat.

Combining these two techniques helped me to greatly improve performance of the script and avoiding user agent freezing. It's still a workaround, but checking for the existence of the touch events seems semantically correct.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top