How to Profile JavaScript Execution

What is the best way to profile javascript execution?

Firebug

Firebug provides a highly detailed profiling report. It will tell you how long each method invocation takes in a giant (detailed) table.

console.profile([title])
//also see
console.trace()

You need to call console.profileEnd () to end your profile block. See the console API here: http://getfirebug.com/wiki/index.php/Console_API

Blackbird

Blackbird also has a simpler profiler

  • Blackbird official site from Wayback Machine
  • Source from Google Code Archive
  • Source from Github (pockata/blackbird-js: A fork of the cool Blackbird logging utility)
  • Source from Github (louisje/blackbirdjs: Blackbird offers a dead-simple way to log messages)

How to profile and get Javascript performance

Regarding memory consumption

Memory leaks in JavaScript are usually ignored except when they turn into browser memory leaks (that is, even after the user navigates away from the page, the memory continues allocated and there's no way to free it). The reason for this is that while your web application may have some memory leaks, users will go from one page into another so the leaks are minimized. However they may not restart the browser, so browser memory leaks may be serious. Some JavaScript code is known to cause memory leaks on certain browsers, being Internet Explorer probably the worst in this area. For it you may find Microsoft JavaScript Memory Leak Detector to be very useful.

Regarding times

IE, Chrome and Safari have built in profilers in the web development tools that ship with the browser. For Firefox you may use Firebug. Also useful may be, since you're using jQuery which means your profiling report will be filled with anonymous functions and alike, making it quite unreadable, John Resig's jQuery profiling plugin, which will give you a clearer output on the matter.

JavaScript profiling with per-statement results

Firebug's and the DevTools' profilers provide you with detailed information on how much time was spent within each function. See the following screenshots:

Firebug (Own Time column)
Profiler output in Firebug

Firefox DevTools (Self Time column)
Profiler output in Firefox DevTools

Chrome DevTools (Self column)
Profiler output in Chrome DevTools

The Firefox DevTools furthermore allow you to include platform data by enabling the option Show Gecko Platform Data within the Performance panel options:

Firefox DevTools *Performance* panel option to include Gecko platform data

Though the tools only display data per-function. They do not allow you to display per-line, or to be more precise, per-statement information, probably because this is something the JavaScript author cannot influence directly.

If you believe that this information can be relevant for a JavaScript author, you should file requests for each of those tools to implement this feature explaining the reasoning behind it.

profiling anonymous javascript functions (chrome)

Probably the easiest way is to put a console.trace() in your function.

Slow javascript execution in chrome, profiler yields (program)

Idle cycles ("doing nothing") will also render as "(program)" (you may profile this SO page for a few seconds and get 100% of (program)), so this is not a sign of something bad in itself.

The other thing is when you actually see your application lagging. Then (program) will be contributed by the V8 bindings code (and the WebCore code they invoke, which is essentially anything: DOM/CSS operations, painting, memory allocations and GCs, what not.) If that is the case, you can record a Timeline of your application (switch to the Timeline panel in Developer Tools and press the Record button in the bottom status bar, then run your application for a while.) You will see many internal events with their timings as horizontal bars. You will see reflows, style recalculations, timers fired, GC events, and more (btw, the latest Chromium versions have an improved memory profiler utilization timeline, so you will be able to monitor the memory used by certain internal factors, too.)

To diagnose memory problems (multiple allocations entailing multiple Full GC cycles) you may use the Profiles panel. Take a heap snapshot before the intensive part of your code starts, and another one after this code has run for some time. Then compare the two heapshots (the right SELECT at the bottom) to see which allocations have taken place, along with their memory impact.

Is using the Date object to count the speed of the Javascript execution correct?

Well generally yes, if you are doing painting, you can factor in a rough painting time as well with:

var start = +new Date();

//Do dom methods draw to canvas etc

setTimeout( function() {
var stop = +new Date();
console.log( stop - start - 13 );
}, 13 );

Also, make sure you call each test as a function and warm-up the functions before timing them instead of doing the code in-line.

function test1() {
//ops
}

function test2() {
//ops
}
var l = 1e5;
while (l--) {
//warmup
test1();
test2();
}
var start = +new Date();
var l = 1e5;

while (l--) {
test1();
}

var stop = +new Date();
console.log(stop - start);

var start = +new Date();
var l = 1e5;

while (l--) {
test2();
}

var stop = +new Date();
console.log(stop - start);

You should note that this setup invites JIT optimizations (which is why it was done in the first place) so you should look out for dead code elimination.

Javascript execution tracking in Chrome - how?

One simple approach is to start Chrome Developer Tools, switch to the Sources panel and hit F8 (Pause Execution). This will break on the first executed JavaScript statement.

Another approach is to set an event listener breakpoint for mousedown or click: in the same Sources panel, expand the "Event Listener Breakpoints" in the righthand sidebar. Expand the "Mouse" item and check the events you want to break on (e.g. "click", "mousedown"). Then go click in your page and see the JS execution break in the DevTools. Enjoy!



Related Topics



Leave a reply



Submit