Question

The mousemove-event in jQuery fires every time the mouse moves, and this can lead to hundreds of event executions per second. Let's say we have this code snippet.

$(document).on('mousemove', function(e){

    /**
    *    This piece of code checks if the mouse is within a 50px range 
    *    on either side of the middle of the page. 
    *    If is, it shows a set of elements (contained in the action_dots variable).
    */

    var treshold = 50;
    var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');
    var opacity = action_dots.css('opacity');

    if(e.pageX >= ($(window).width()/2 - treshold) && e.pageX <= ($(window).width()/2 + treshold)){
        if(opacity == 0){
            action_dots.transition({ opacity: 1 }, 100);
        }
    }
    else{
        if(opacity == 1){
            action_dots.transition({ opacity: 0 }, 100);
        }
    }
});

Is it efficient to declare those variables every time the event executes? Since it has to find all the elements matching the selector of var action_dots, you could think it is a burden on performance. Or can jQuery somehow cache the contents of var action_dots? Same questios apply to checking the action dots' opacity css-property with the var opacity.

Was it helpful?

Solution

In terms of efficiency, no it's not very efficient to run that code for every single pixel the mouse moves. What you could do is run that code after the mouse has stopped moving for x miliseconds. Something like this:

var mouseTimer;
$(document).on('mousemove', function(e) {
    clearTimeout(mouseTimer);
    mouseTimer = setTimeout(function() {    
        var treshold = 50;
        var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');
        var opacity = action_dots.css('opacity');

        if (e.pageX >= ($(window).width() / 2 - treshold) && e.pageX <= ($(window).width() / 2 + treshold)) {
            if (opacity == 0) {
                action_dots.transition({ opacity: 1 }, 100);
             }
        }
        else {
            if (opacity == 1) {
                action_dots.transition({ opacity: 0 }, 100);
            }
        }
    }, 50); // runs 50ms after mouse movement stops.
});

OTHER TIPS

As per my comment: If the dots are not added dynamically you simply declare action_dots outside the $(document).on call so it gets filled once at page ready time.

$(function(){ // JQuery ready - modern version

    var action_dots = $('.branch[open][focus]').children('.branch-line').children('.action-dot');

    $(document).on('mousemove', function(e){

        /**
        *    This piece of code checks if the mouse is within a 50px range 
        *    on either side of the middle of the page. 
        *    If is, it shows a set of elements (contained in the action_dots variable).
        */

        var treshold = 50;
        var opacity = action_dots.css('opacity');

        if(e.pageX >= ($(window).width()/2 - treshold) && e.pageX <= ($(window).width()/2 + treshold)){
            if(opacity == 0){
                action_dots.transition({ opacity: 1 }, 100);
            }
        }
        else{
            if(opacity == 1){
                action_dots.transition({ opacity: 0 }, 100);
            }
        }
    });
});

That JQuery selector is the slowest part of your code, but probably only needs to be run once (or at least only once each time a new item is added to the page - if it is dynamic).

Please post the whole JS if you want a specific example (just incase you are missing the JQuery "ready wrapper" - not shown).

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