How to profile and get Javascript performance [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to profile javascript execution?
I have a few scripts that use jQuery, and I think I have a memory leak in one of them.
How one could profile and find what parts of the scripts that I have are using the most memory/CPU?

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.

Use Firebug. To quote from http://getfirebug.com/js.html:
To use the profiler, just go to the Console tab and click the "Profile" button. Then use your app for a bit or reload the page and then click the "Profile" button again. You'll then see a detailed report that shows what functions were called and how much time each one took.

I would suggest taking a look at the profiler in Firebug, and the Drip plugin for IE to help look for memory leaks.
Also, just keep in mind that most javascript memory leaks come from circular references between DOM objects and javascript objects not being broken when the DOM object is unloaded. To prevent that, I would suggest avoiding creating references to javascript objects in DOM object properties (ie, avoid something like document.getElementById('foo').bar = myObject;). If you must create these circular references, be sure to break them yourself in a function that runs when the page unloads, or when removing the DOM objects prior to unload.

Google Chrome also has profile options

Another simple way to test a specific piece of code is to add a timer around it.
var testStart = new Date();
// code to be tested here
$('#jstest').html("selected function: "+ (new Date() - testStart) + " milliseconds");
Where jstest is a span element somewhere visible on your page.

Though chrome has profiling options inbuilt it does not give precise information about the object.So i prefer using leak-finder-for-javascript tool which helped me in my code.
https://code.google.com/p/leak-finder-for-javascript/
I hope this helps.

Firebug or Google's Page Speed for Firefox have profiling tools.

This post by John Resig (jQuery) may be helpful for detecting memory leaks in IE:
http://ejohn.org/blog/deep-tracing-of-internet-explorer/

Related

Diagnosing memory leaks with page reload

I suspect my one-page javascript app contains a memory leak somewhere. Weak devices running Firefox or Chrome seem to crash eventually if the page is left open. I'm trying to determine whether reloading the page would be expected to free the memory or not.
I understand that memory handling is specific to the browser, so the answer may differ in Chrome or Firefox.
NOTE: I recognize that browsers are mentioned a lot in this question (which would be off topic), but the point of this question is about javascript debugging, which I think is very on topic.
Barring browser/extension bug, browsers free up resources when they are no longer needed; Firefox clears compartments, Chrome kills processes and associated storage.
Firefox does its best but may take some time to clear the memory and may create zombie compartments on occasion:
Compartments are destroyed when they are garbage collected. This happens some time after the last reference to them disappears. This means there can be a delay between a page being closed and its compartments disappearing...
Sometimes, due to bugs in Firefox, the Add-on SDK and/or add-ons, compartments are created that are never destroyed. These are a particular kind of memory leak, and they cause Firefox's memory usage to increase gradually over time, slowing it down and making it more likely to crash.
Chrome uses a process per tab (and really subprocesses for some entities within a tab as well IIRC e.g. plugins, iframes, etc.) to the same effect. Though a quick check against chrome://memory-redirect/ and refreshing a tab looks like the same pid is used. So a refresh is not a completely clean slate.
FWIW Chrome has a "Force Reload" that clears the cache and might be either useful for clearing more memory or a placebo: cmd-shift-r
I'm not really familiar with the internals but I've only seen things not reliably freed up between refreshes when a particular browser is getting too clever and trying to preserve things when you're not changing origins etc. in an effort to boost load performance.
In short, you could be tripping up a browser bug if you're not seeing memory freed as you expect but you'd want to use the various "about:memory" tools to verify that and at that point it would be on you to avoid such behavior and/or report the issue to the browser's dev team.
Otherwise, I think you're best served by addressing your own memory leaks within the page using the various tools available.
A good way to debug the resource usage of JS is to use the Firefox performance monitor within the inspection tool. Firefox Dev Edition has more in-depth tools
Press F12 when on the page and click on the little speedometer icon in the inspect window; this will open the performance monitor. Press the "Start Recording" button and Firefox will begin to benchmark all script timings, CSS activity, user input etc. on the page.
When you feel that it has been running for long enough, stop recording and you will be presented with all the data. At the top will be a chart displaying performance and you can click on any part and examine all the scripts running at that time.
A full tutorial for the performance tools can be found here

How to find JS Memory Leaks?

I have struggled around with the heap profiler in chrome but it is very confusing. Especially if there are minimized libraries inside. But even the DOMElements views, elements which may not be removed are very unclear presented.
Are there any tips how to use the heap dump in chrome to find JS code that leads to memory leaks, code that cannot be cleaned by GC... and how to find elements messing around even if removed from dom?
In other words, how to read heap dump in chrome correctly? Dominators View? Comparison?
Chrome now offers much better tools to find memory leaks, than at the time of most answers.
Here is to find memory leaks in javascript with a recent Chrome browser:
Press F12 to open the developer tools and go to the Memory Tab.
Pick a feature or a part of your app that you want to inspect for leaks. For example, when a dialog is opened and closed again, the memory used by it should be released.
Do the action (for example opening a dialog) you want to check for memory leaks once, so potential global services can be loaded. This prevents these objects, that are intentionally preserved from showing up as leaks.
Now select Record Allocation Timeline and press Start. Repeat the action you want to check for leaks a few times. So for example open a dialog, close it and repeat. While you do this Chrome draws the timeline with partially grey or blue bars. Usually you see a bar for each time you performed the action on your page. When the bar from several previous iterations of the action stays partially blue it usually means there is a memory leak. The blue part of the bar represents memory that was allocated at this time and has not yet been released again. Stop the recording by pressing the red dot on the top left of the developer tools.
When you see potential leaks you have to inspect this part of the timeline to find the source. Select a part of the timeline that is a few iterations of your actions in the past. And Chrome will show a list of object-types that are still present in the memory. The retained size column gives you an impression how much memory is still used. Browse into one of the object-types and select an object. If you do that, the list of retainers will appear below.
The list of retainers shows the "parent" objects that reference the selected object. Now you need to look at the retainers and your code to understand why the memory has not been released. For example in the image you see the object of the type scope. The second line says the scope is "context in initFormat()". The problem was that initFormat was an event listener that was not unbound after a dialog was left.
After you fixed your code check if the problem has been solved. Refresh the page and repeat the steps 3 to 6 again. If you have never checked for memory leaks before it is not unlikely that you find multiple problems.
Additional hints:
Sometimes there are caches that retain a part of the memory. Usually you can ignore them.
When you see the HTMLDivElement or other DOM elements in the list of object-types have a look. If the objects in this list are highlighted red it means they are no longer present in your page. This means they must be reference somewhere in the code. You may have forgotten to unbind an event listener.
Read about memory leaks in general, so you can identify them quicker in your code.
In Chrome developer tools, there is a Timeline - Memory tab:
We can watch the memory occupied by it.
There is also Profiles - Memory, where we can take a snapshot and see what’s inside. Snapshots can be compared to each other:
Most of time, it doesn’t tell you anything. But at least you can see which objects are piling up, and probably the structure of the leak.
Other way is using 'Task Manager'
here is an article regarding this:
http://www.javascriptkit.com/javatutors/closuresleak/
Google open sourced a tool for this purpose, leak-finder-for-javascript. They also proposed a method so-called the three snapshot technique (also see a brief description in this article).
First paragraph of the leak-finder link
Note: jsleakcheck is no longer supported! It was working against an unofficial and unstable Dev Tools protocol for taking heap snapshots.
The protocol is being worked on, and it is not stable enough so that I
could keep jsleakcheck working with various Chrome versions. In
addition, a lower level compatibility tool,
remote_inspector_client.py, which jsleakcheck was using to communicate
with Dev Tools, got removed.
I found this article very insightful:
http://addyosmani.com/blog/taming-the-unicorn-easing-javascript-memory-profiling-in-devtools/
It does cover the chrome developer tools extensively and explains very well how to go about when your application seems to have memory issues.
Quoted from JavaScript Kit:
If you are developing client-side re-usable scripting objects, sooner or later you will find yourself spotting out memory leaks. Chances are that your browser will suck memory like a sponge and you will hardly be able to find a reason why your lovely DHTML navigation's responsiveness decreases severely after visiting a couple of pages within your site.
A Microsoft developer Justin Rogers has described IE leak patterns in his excellent article (from web.archive.org).
In this article, we will review those patterns from a slightly different perspective and support it with diagrams and memory utilization graphs. We will also introduce several subtler leak scenarios. Before we begin, I strongly recommend you to read that article if you have not already read.
Why does the memory leak?
The problem of memory leakage is not just limited to Internet Explorer. Almost any browser (including but not limited to Mozilla, Netscape and Opera) will leak memory if you provide adequate conditions (and it is not that hard to do so, as we will see shortly). But (in my humble opinion, ymmv etc.) Internet Explorer is the king of leakers.
Don't get me wrong. I do not belong to the crowd yelling "Hey IE has memory leaks, checkout this new tool [link-to-tool] and see for yourself". Let us discuss how crappy Internet Explorer is and cover up all the flaws in other browsers".
Each browser has its own strengths and weaknesses. For instance, Mozilla consumes too much of memory at initial boot, it is not good in string and array operations; Opera may crash if you write a ridiculously complex DHTML script which confuses its rendering engine.
Although we will be focusing on the memory leaking situations in Internet Explorer, this discussion is equally applicable to other browsers.
continue reading...
Here is a very good post about how to find memory leaks using the Google Developper Tools: http://gent.ilcore.com/2011/08/finding-memory-leaks.html
Here is another good web page about that : http://javascript.crockford.com/memory/leak.html
I don't see mentioned window.performance.memory, which gives you the run-time ability to monitor and take action based on memory usage.
window.performance.memory:
MemoryInfo {
totalJSHeapSize: 7084834,
usedJSHeapSize: 6486770,
jsHeapSizeLimit: 4294705152
}
For a handy percentage, use this:
window.performance.memory.usedJSHeapSize / window.performance.memory.jsHeapSizeLimit
https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory

JavaScript: should I worry about memory leaks in 2011?

The topic of memory leaks in JavaScript is not brought up often. However, I stumbled upon this article, written in 2007. The authors state:
Internet Explorer and Mozilla Firefox are the two Web browsers most
commonly associated with memory leaks in JavaScript.
Should I still be worrying about JavaScript memory leaks in 2011? If so, what should I be careful about?
A good javascript developer would be aware of various design patterns that can lead to memory leaks and you'd avoid coding anything that could turn in to a leak in pretty much all the pages you code.
For example, keeping a reference to any DOM object in a javascript variable will keep that DOM object alive in memory even if it's long since been removed from the DOM and you intended for it to be freed.
Practically speaking, leaks are only significant in some circumstances. Here's where I specifically worry about them:
Anything I'm doing repetitively on a timer, particularly if it can be left running for a long time. For example, if you have a slideshow that might just loop forever, you have to make absolutely sure that nothing in the slideshow is an accumulating leak of either JS or DOM objects.
A web page that works like an app and the user may stay on the same page for a long time, interacting with the page, doing ajax calls, etc... For example a web mail app might be open and on the same actual browser document for a very long time doing lots and lots of user and server interactions.
A web page that regularly creates and destroys lots of DOM elements like something that regularly uses ajax to fetch a bunch of new HTML.
Places where I don't really worry about leaks:
A web page that doesn't have a long running set of interactions the user can do.
A web page that doesn't stay on screen very long before some other page is loaded or this page is reloaded.
Some of the key things I keep an eye out for.
Any lasting JS variables or properties that contain references to DOM elements when DOM elements are being created/destroyed.
Any properties of a DOM object that contain references to other DOM objects or references to JS objects that contain reference to other DOM objects (this can create circular references and cross references between JS/DOM that some older browsers have trouble freeing).
Any large data structures that I load for temporary use. I make sure that no references to these large data structures are every kept around.
Any data caches. Make sure nothing really large gets cached that you don't want cached. Make sure all caches that get used repeatedly don't accumulate forever and have some sort of aging mechanism to get rid of old objects.
Yes, memory leaks are definitely a problem in JavaScript, since circular references are indeed possible. A very common source of memory leaks is the use of closures. As an example, consider:
var outerFunction = function(param1, param2, param3) {
var innerFunction = function() {};
return innerFunction;
};
It is possible for the above to leak the parameters, since innerFunction holds a reference to the scope in which it was constructed, which includes the parameters to that frame.
While it is easy for these sorts of things to go unnoticed on many desktop computers, where there is plenty of RAM, this is actually something that can be very obvious on devices with limited RAM (e.g. a mobile phone or a set top box). As an anecdotal example, a couple websites that shall remain unnamed used to crash on me quite frequently when visited from my TV, which has very limited RAM.
Note that these problems are with the JavaScript code written by web developers. Memory leaks in the underlying JavaScript interpreters, while possible, are far less of an issue, and isn't something that web developers can reasonably concern themselves about, since that's the job of the browser writers.
NO.
More complete answer: maybe. The fact you are asking so vaguely is a strong signal that you personally are unlikely to need to worry.
In practice, the vast majority of JavaScript code simply doesn't worry about it, and doesn't need to worry about it because only in particular circumstances do memory leaks in pages end up affecting users. The browser and frameworks cover your arse pretty well.
There are only a few questions you need to answer:
Q: Are you supporting a rich single page application that uses JavaScript heavily?
If not, then don't waste your time worrying. If you (or your QA, or your clients) find a memory over-usage issue with a page then fix it when it comes up.
Q: Do you need to support mobile devices, and you have heavy javascript usage?
Mobile devices have limited memory and extra care needs to be taken.
If you ARE developing a JavaScript heavy application, and you need to worry about memory usage, then...
The issue of "dirty" references to objects that cause JavaScript objects and DOM objects to never get garbage collected is important to certain types of JavaScript applications. Caches that grow forever, unexpected global references, and unexpected references inside closures can be a problem.
The Heap Snapshot tool in Chrome's Web Inspector can help.
Here is a git project that has a useful writup and walks the javascript objects it can: https://github.com/tlrobinson/leakhelper
There are other tools that help you, but I wrote my own over time:
1. our framework marks deleted widgets, so I wrote code to walk all arrays and objects from window or document looking for the paths to delected objects (javascript code can't walk closures but it definitely helped find some leaks).
2. Another trick I used was when widget x was deleted, I do a x.leakhelper = window.createElement('leakhelper') and setAttribute the oid of the widget, but not add the element into the document. If the DOM element is not garbage collected then the widget must have a dangling reference to it somewhere. In IE use window.collectGarbage() to force the GC, and use sIEve to detect the leaked DOM element (I found sIEve to be really useful).
Obsolete question: Do you need to strongly support either IE6 or IE7 AND you use JavaScript heavily? Most of the scary leaks you used to read about only occur in < IE8. If you are supporting IE6 or IE7 then you need good luck and perseverence (all frameworks leak, and it is hard to write code that doesn't even with a perfect framework - I ended up writing my own IE leak prevention code for our production use for IE6/7 users). The IE6/IE7 leaks can last even after you close your page - which is why they are so nasty.
Well, people still use old versions of IE. So beware of circular references, because IE has severe problems with that. I believe the common mistake in that regard is to reference an HTML element in a closure that is inside an event handler to that element. Just set the variable referring to the element to null and it'll be fine.
It really depends on 2 things -
Average run-time expectation of your application. Simple jquery lightbox or carusel on main page of online shop can leak (and often does, because, they are coded so badly), but nobody will notice (because the page is closed or refreshed within couple of minutes or less). But Node.js server, full-ajax social network, browser game or online IDE - can run for hours or even days non-stop.
I/O complexity of your application. The more you touch DOM, XHR/network, files, DOM/UI events, the more times you redraw the screen (be it canvas, html or svg) - the bigger is risk for leaks, memory hogging (which is NOT a leak) and running into browser bugs.
Good thing for you is - those two things correlate with each other. So, you either write shovel-code like no tomorrow, or engineer for performance, endurance, and robustness.
p.s.: if you have to support IE8-, you are not in 2011, yet. So you just have to worry, like in good old times.

How can I avoid causing memory leaks in Firefox?

It seems that there is a lot of information on memory leaks in IE and how web developers can avoid them, but I can't find much on avoiding leaks in FF. I've found lots of random tips on how end users can tweak their preferences, or tips for extension developers, but little on what I can do as a web developer to make sure my pages don't leak. Am I missing something? It seems lazy to just blame it on the user and say "you've got too many extensions". Or are the major patterns the same as in IE -- circular references and all that?
Also, if anyone knows of any tools to troubleshoot leaks in FF, that would be great. I found this:
https://addons.mozilla.org/en-US/firefox/addon/2490/
But it's apparently just for chrome and extension development.
Outside of the design patterns to favour the only truely safe way is to test your pages thoroughly. To monitor the memory usage of the browser Task Manager is alright but Process Explorer provides more accurate results.
JavaScript is one cause of memory leaks but be careful with flash movies on pages too. Our content team added a movie from our design department that used a thrid party transition affect and this swallowed 10Mb every 20s or so. Just watching the movie loop through it was obvious in TaskManager to see the memory jump when the affect occured and the it never quite release it all back.
You can force to run a Garbage Collector in FireFox. The Garbadge Collector will destroy & release objects that are not used anymore. The only possibility of "Leaking memory" with a Garbage Collector is not a "leak" but a reference which makes no sense: remove all references to objects that you don't want to use.
Read more on this page:
http://adblockplus.org/blog/different-ways-to-force-garbage-collection
A bunch of what you read about how to avoid memory leaks in browsers is about how to avoid things that cause the browser to fail to reclaim memory that it should reclaim.
However, a more substantial problem in many cases is about Web pages holding on to objects that they don't need anymore. It's only the browser's job to reclaim things that are no longer "reachable" -- that is, things that the script / page can't get to anymore. If you're accumulating objects in an array and not removing them when you're done with them, memory usage will go up as the array gets bigger, and there's nothing the browser can do about that.
To phrase that another way: that's an issue of a memory leak in the Web page rather than in the browser. And the tool you want for that is a memory profiling tool to examine the objects that are reachable in your page, so you can tell whether there's stuff in there that you should no longer be holding on to. Writing such a tool for Firefox has been on my list of things to do for a while, but I haven't gotten around to it yet. I think there might be some ongoing work on writing one that integrates into Firebug.
I don't know if there is specific information for Firefox, but the generic tips still apply.
I suggest that you closely examine all loops and recursive functions. Re-use existing objects over creating new ones, and ensure that temporary objects and primitives exit scope so that they can be freed.

What are some of the best Javascript memory detecting tools?

Our team is faced with slow but serious Javascript memory leak. We have read up on the normal causes for memory leaks in Javascript (eg. closures and circular references).
We tried to avoid those pitfalls in the code but it likely we still have unknown mistakes left.
I started my search for available tools but would like input from people with actual experience with these tools.
Some of the tools I found so far (but have no idea how good and useful they would be for our problem):
Sieve
Drip
JavaScript Memory Leak Detector
Our search is not limited to free tools, it will be a bonus, but more importantly something that will get the job done.
We do the following in our Javascript code:
AJAX calls to a .NET WCF back-end that send back JSON data
Manipulate the DOM
Keep a fairly sized object model in the Javascript to store current state
sIEve is for memory leaks in IE specifically. What I like about it is that you can reliably reproduce the steps used and capture action-able data. See the following:
How to use IE7 Javascript memory leak detectors?
Another tool for you: JavaScript Memory Validator.
Shows allocations, objects, hotspots, generations, snapshots, etc.
Works with Firefox 1.0 through 3.6.
I have used the JavaScript Memory Leak Detector and I can tell you it works great.
What dynamic engine are you using? Based on the mention of a .Net web service, I'm guessing that you are using ASP.Net. Is that correct? You may want to look at the ASP.Net AJAX JavaScript library. It was built in a way that helps this situation. All components have a dispose() method that allows you to remove references to DOM objects. When I switched to ASP.Net AJAX, my page became much more responsive.

Categories