We are facing a problem with jQuery event propagation performance connected to mousemove:
We have a screen filling canvas and need to track if a user drags the mouse on it, so we have added a mouse move listener on that object like this:
ourCanvas.on('mousemove',
function(event) {
event.preventDefault();
//our drag code here
}
});
This code works fine, but we had severe performance issues in the current Firefox (24) on one test system. The profiler tells us, that most of the time was spent in jQuery.event.dispatch()
(we tried current latest jQuery 1.8, 1.9, 1.10 and 2.0).
We successfully decreased the time spent in the dispatch() function by using the "jQuery.event.fix()" performance optimization here: http://bitovi.com/blog/2012/04/faster-jquery-event-fix.html but performance on that test system was still way below what we expected.
After some further testing, I managed to pin this down on the mouse used on the system: It used 1000Hz. We switched the used mouse down to 125Hz and voila, the performance was great.
Our assumption was, that the high Hz rate on the mouse caused a lot of mousemove events, so we changed the above code to apply an event throttle and only call the event handling every X milliseconds:
var lastMove = 0;
var eventThrottle = 1;
ourCanvas.on('mousemove',
function(event) {
event.preventDefault();
var now = Date.now();
if (now > lastMove + eventThrottle) {
lastMove = now;
//our drag code here
}
}
});
And it worked like a charme, the performance was great. Even though we only skip two milliseconds of events.
Now I have two questions:
We have other locations where we attach mousemove listeners to different HTML elements and I'd like to add this hand-made throttle to all of those
mousemove
handlers to not run into the problem again. Is this somehow possible to do in a nice way in jQuery (2.0.3)? I've seenpreDispatch
hooks in the jQuery javascript but they are already after the call to fix() which also uses some time and I'd like to save that call as well.I was puzzled by the fact that already an
eventThrottle
of 2ms was sufficient to get really good performance so I added a counter to see how many events are being skipped. The surprising result: it skips only 0-1 events... With a throttle of 100ms, the skipped events were in the order of 60-70, so if there is less than 1 mousemove event per ms, why does this code have such a positive effect after all?
Thanks for any comments, Christopher