Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ignore libraries like jQuery when profiling JavaScript?

Of course, Firebug, Chrome's Web Inspector, Opera's Dragonfly and dynaTrace's AJAX tools for IE have profiling capabilities. However, I haven't found a tool that lets me 'ignore' a library.

To give an example, suppose I have the following pure JS/DOM code:

function foo(node) {
    for (var i = 0; i < node.childNodes.length; i++) {
        node.childNodes[i].innerHTML = 'Test';
    }
}

and a similar bit of code that uses jQuery:

function bar(jqNode) {
    jqNode.children().each(function() {
        $(this).html('Test');
    });
}

(examples aren't exactly great code, please leave them be as that isn't the point)

If you throw both through a JS profiler, you'll find that in the first example, there's just one function where the 'own time' of the function equals the 'total' time spent in the function - as the DOM manipulations get counted as 'own time'.

In the jQuery example, however, all of this is abstracted away into jQuery, which means the 'own time' is minimal and all the time is spent in jQuery.

This makes it very hard to find performance bottlenecks, because the functions with the highest 'own time' are jQuery.fix and jQuery.init and such (which doesn't tell me anything about how well-written (or not) my code is), and the functions with the highest 'total time' are usually too high up the call stack to find out where the actual problem is (if you have one function that calls 10 others, and one takes 'forever', the calling function will have a bigger 'total time' but that won't let you figure out which of the called functions take the longest').

like image 490
Gijs Avatar asked Dec 05 '11 12:12

Gijs


1 Answers

Filtering out libraries is not what you want and AFAIK no profiler does it the way you want it to. Besides, if your code is badly written because it is abusing library calls, you want to see which library calls it is abusing.

Use the built-in Chrome profiler in "Tree (Top Down)" mode. (Select the mode at the bottom of the Self and Total columns.) In this mode you can see the total time each function takes along with the total time spent in each function that function calls and so on down to the leaf functions that call no other functions. So in your function bar() you will see the total time spent in bar and below that, the total time spent by bar calling each and so forth. (Now with jQuery it can get a bit convoluted, but that's not really the point.)

So if you have one function that calls 10 others, and one takes 'forever', the calling function will have a bigger 'total time' and you figure out which of the called functions take the longest by clicking on the triangle and expanding the 'forever' function and looking at the total time of each of the functions it calls. If 9 take little time and 1 takes forever, then that's the culprit and you keep drilling down until you find the problem.

EDIT: A few more tips on using Chrome's profiler

  • Use "Heavy (Bottom up)" view to find leaf functions that are taking a lot of time. The triangles display who calls them.
  • option-click on a triangle to open the entire tree. Saves lots of clicking through deeply nested call chains.
  • "(program)" refers to the part of the time the profiler was running during which no JavaScript was running. Things like rendering the HTML.

You can do filtering and focusing on a per-function basis. Read the documentation for details on this and more.

like image 66
Old Pro Avatar answered Oct 01 '22 10:10

Old Pro