Javascript memory usage management
I am building large website with heavy javascript usage, all of my content is being loaded trough ajax
, it is very similar to facebook, and since there is a lot of different pages i need a lot of javascript, so what i thought of is to divide my script in to sections, each page would have it's own script file.
Now loading is simple, i just load a new file with each page, but my concern is what will happen if user goes trough 100 different pages and load 100 different script files?
At the moment my website doesn't have that many pages, but i'm quite sure it will grow to nearly 100 unique pages at some point in the future.
So what would happen to the user with slower computer? Im guessing it would start to slow down a lot since there would be no refresh. From what i have read it is impossible to just unload all events and data from loaded script file in any easy way, and if i were to try that it might cost me a way to much time and effort to do that.
So my question would be, should i just leave it the way it is or try to do something about it? I am currently using jquery
with few plugins, and if i had to guess average file would be around 50-200 lines of code with mostly click
events, and ajax
calls.
Note, each page objects has it's own prefix for each class, for example: home_header
, login_header
So there shouldn't be any conflicts between onClick
event listeners and similar things.
EDIT I'm setting bounty on this question, i would like to hear more opinions.
Just because you are using AJAX doesn't automatically mean alarm bells with regards to memory usage... you should be more worried about the kind of things that cause memory leaks, and making sure you destruct as well as construct things properly:
http://www.ibm.com/developerworks/web/library/wa-memleak/
What is JavaScript garbage collection?
As a rule, in any large system I tend to create a helper constructor that keeps track of all the items I may wish to destroy at a later date or on page unload (event listeners, large attributes or object structures) all indexed by a namespace. Then when I've finished with a particular section or entity I ask the helper system - I call it GarbageMonkey :) - to clear a particular namespace.
Obviously for the above to work you need to be wary about leaving variables lying around that can keep a reference to the data you hope to delete. So this means being aware of what garbage collection is, what closures are; and how between them they can keep a variable alive forever!! ..or at least until the browser/tab is destroyed. It also means using object structures rather than vars because you can delete keys in any scope that has access to the object, but you cannot do so for vars.
So do this:
var data = {}, methods = {}, events = {};
methods.aTestMethod = function(){
/// by assigning properties to an object, you can easily remove them later
data.value1 = 123;
data.value2 = 456;
data.value3 = 789;
}
Instead of this:
var value1, value2, value3;
var aTestMethod = function(){
value1 = 123;
value2 = 456;
value3 = 789;
}
The reason being because in the above you can later do this:
var i;
for( i in methods ){ delete methods[i]; }
for( i in data ){ delete data[i]; }
But you can't do this:
delete value1;
delete value2;
delete value3;
Now obviously the above wont protect you from a reference that points directly to a sub element of either methods
or data
. But if you only pass the methods
and data
objects around in your code, and keep tidy with regards to attaching methods as event listeners, then even if you do end up with a rogue reference it should only point to an empty object (after you've deleted it's contents that is).
If you recycle variables and don't pollute the global scope, you're on the right track; but as for your question, you should first find out if it is a practical concern.
This can be checked and monitored with a profiler - out-of-the box Chrome is pretty decent for it, just type about:memory
in the URL and it'll give you a per-tab breakdown and would even let you compare memory usage between browsers. If you have some automated test scenarios set up (or are willing to navigate through 100 pages manually), such profiling will tell you if there's something majorly wrong with your website.
There is 2 different thing to take care of :
-memory usage
-memory leaks
For long-running webapps, memory leaks should be absolutely avoided, otherwise users will experience browser crashes. To monitor memory use, you can download process explorer : http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Disable all your browser plugins, and then use your app, and perform repetitive tasks. If memory use raises, you got leaks. IE7 - IE8 do leak much more easily than modern browsers, and are much harder to debug, so it is useful to know what is you minim browser compatibility.
For memory usage, a few thing can help decrease the weight of your app :
instead of looping through dom elements and attaching event handlers functions, use event delegation. ED is really a golden gun here.
for IE 7 / 8 var nullification was necessary and I think it still helps for modern browsers(needs some testing). To do so, you need also to name your functions, so that you can remove them from memory. (see pebbl answers for more details on this)
keep control of the dom size. When nodes are added for a feature, they should also be removed when this feature is not used anymore.
add to all of your components some teardown() method that handles unloading.
ok, sorry I am a bit too quick here, but it would be nice to know :
what is your minimum browser
if you have detected leaks
if ED is a sufficient solution (often it is)
上一篇: JavaScript匿名函数垃圾回收
下一篇: Javascript内存使用管理