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.
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);
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.