When carrying out a profiling like this, be advised of the observer effect. The extra monitoring adds a certain overhead to the code execution and hence, the actual timing would be different to the case where there is no instrumentation at all. The difference is usually minimal, in particular since the entire application is affected. Yet, take that into account as you move forward to make any conclusion.
While timing information obtained from the profiler is useful, sometimes you are also interested not in how fast a certain operation is carried out, but also what happens during that time. This is like doing an X-ray on your program execution. Fortunately most modern browsers support the console API
console.trace will give you exactly that information:
Scalability is another excellent area of application tracing. If you have an address book application, sorting the contacts the alphabetically can be really fast if you only have 10 entries. However, here you are not interested in the absolute time of the sorting. You also want to know how it handles the address book with 100 entries, 1000 entries, and so on.
Formal analysis of the complexity can be complicated or prohibitively expensive. This is where empirical run-time analysis kicks in. For example, you can instrument
Array#swap and plot the number of function calls vs address book entries. If your team member implemented it using bubble sort instead of something faster like binary sort, that chart will reveal it.
After you locate the problematic spot in the performance, the next step is obviously to fix it. In many cases, speeding up some parts of the application is not really difficult. In other cases, you have to try different strategies and see which one fits the performance criteria. Often, it is as simple as figuring out which implementation is the fastest. This is where timing the execution of a function is useful.
Beside careful timing, it is also important to pay attention to the benchmark corpus. Whenever possible, choose something which resembles its real-world usage. For example, if you try different ways to sort the contacts in the address book application, make sure you supply a representative list for the benchmarks, more than just a useless array of
['a', 'b', 'c'].
Last but not least, remember that optimization is not the destination, it is a journey!