Coding with Jesse

Detecting and Debugging Timeouts and Intervals

May 28th, 2007

When you start to cram a lot of JavaScript animations and Ajax onto a web page, it can become tricky to know all the code that's running in the background. When you start to detect some performance issues, it's equally tricky to track down what code is being executed.

Luckily, the only way to get code to run in the background with JavaScript is through the functions setTimeout and setInterval. And more luckily, we can overwrite these functions so that we can know whenever they are being called:

window.setInterval_old = window.setInterval;
window.setInterval = function(fn, time){
    console.log('interval', fn.toString(), time);

    return window.setInterval_old(function(){
        console.log('interval executed', fn.toString());
        fn();
    }, time);
};

window.setTimeout_old = window.setTimeout;
window.setTimeout = function(fn, time){
    console.log('timeout', fn.toString(), time);

    return window.setTimeout_old(function(){
        console.log('timeout executed', fn.toString());
        fn();
    }, time);
};

This will send output to Firebug whenever a timeout or interval is first initiated, and again when the function is actually called.

This solution is rather nice because it will let you know what 3rd party JavaScript widgets are doing in the background as well without needing to add debugging messages to them. You could overwrite nearly any method like this to get similar debugging messages as well (like document.getElementById or Array.prototype.push or practically anything).


Comments

1 . hp on August 21st, 2007

hp

very good!!!

2 . Jim on April 16th, 2008

Jim

Thanks, a lot. But it doesn't work for me.

"fn is not a function"

:(

Please, help me.

JIM

3 . Jesse Skinner on April 16th, 2008

Jesse Skinner

@Jim, does it work when you run these?

setTimeout(function(){ console.log('setTimeout()'); }, 100);
setInterval(function(){ console.log('setInterval()'); }, 1000);

If not, could you paste your code?

4 . Jim on April 16th, 2008

Jim

It works fine.

My code is the problem.

I'll send a mail with the code and more details.

Thanks.


JIM

5 . Yohann.M on November 15th, 2010

Yohann.M

This didn't work for me either. Here my improvments:

window.setTimeout_old = window.setTimeout;
window.setTimeout = function(fn, time){
console.log('setTimeout for "' + fn.toString() + '" ' + (time/1000) + "s");
return window.setTimeout_old(function(){
console.log('setTimeout ended - Executing ' + ' ' + fn.toString());
eval(fn);
}, time);
};

Comments are closed, but I'd still love to hear your thoughts.