简体   繁体   English

Javascript内存使用管理

[英]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. 我正在构建具有大量javascript使用的大型网站,我的所有内容都通过ajax加载,它与facebook非常相似,并且因为有很多不同的页面我需要大量的javascript,所以我想到的是将我的脚本分成几个部分,每个页面都有自己的脚本文件。

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? 现在加载很简单,我只是为每个页面加载一个新文件,但我担心如果用户通过100个不同的页面加载100个不同的脚本文件会发生什么?

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. 目前我的网站没有那么多页面,但我很确定它将来会在某个时候发展到近100个独特的页面。

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. 我目前正在使用带有少量插件的jquery ,如果我不得不猜测平均文件将是大约50-200行代码,主要是click事件和ajax调用。

Note, each page objects has it's own prefix for each class, for example: home_header , login_header 注意,每个页面对象都有自己的每个类的前缀,例如: home_headerlogin_header

So there shouldn't be any conflicts between onClick event listeners and similar things. 因此onClick事件侦听器和类似的东西之间不应该有任何冲突。

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: 仅仅因为你使用AJAX并不会自动意味着关于内存使用的警钟...你应该更担心导致内存泄漏的事情,并确保你破坏以及正确构建事物:

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. 然后当我完成一个特定的部分或实体时,我问帮助器系统 - 我称之为GarbageMonkey :) - 清除特定的命名空间。

  1. For events it unbinds 对于它解开的事件
  2. For attributes it unsets 对于属性,它取消设置
  3. For arrays / objects it scans and unsets each key and can do so for sub elements too 对于数组/对象,它会扫描和取消设置每个键,也可以为子元素执行此操作
  4. For elements it removes and cleans content as much as possible 对于元素,它会尽可能地删除和清除内容

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 . 现在显然上面的内容不会保护您免受直接指向methodsdata的子元素的引用。 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) . 但是如果你只在代码中传递methodsdata对象,并且在将方法作为事件监听器附加方面保持整洁,那么即使你最终得到一个流氓引用它也应该只指向一个空对象(在你之后)我删除了它的内容

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. 这可以通过分析器进行检查和监控 - 开箱即用Chrome非常不错 ,只需在URL中键入about:memory ,它就会为您提供每个标签的细分,甚至可以让您比较内存使用情况浏览器之间。 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. 如果您设置了一些自动化测试方案(或者愿意手动浏览100页),则此类概要分析将告诉您网站是否存在严重错误。

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. 对于长时间运行的webapps,应该绝对避免内存泄漏,否则用户将遇到浏览器崩溃。 To monitor memory use, you can download process explorer : http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx 要监视内存使用情况,可以下载进程资源管理器: 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. IE7 - IE8确实比现代浏览器更容易泄漏,而且调试起来要困难得多,所以知道什么是最小的浏览器兼容性很有用。

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. 而不是循环遍历dom元素并附加事件处理程序函数,使用事件委托。 ED is really a golden gun here. ED在这里真的是一把金枪。

  • for IE 7 / 8 var nullification was necessary and I think it still helps for modern browsers(needs some testing). 对于IE 7/8 var无效是必要的,我认为它仍然有助于现代浏览器(需要一些测试)。 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) (有关详细信息,请参阅pebbl答案)

  • keep control of the dom size. 控制dom大小。 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. 向所有组件添加一些处理卸载的teardown()方法。

ok, sorry I am a bit too quick here, but it would be nice to know : 好的,对不起,我在这里有点太快了,但是很高兴知道:

  1. what is your minimum browser 什么是你的最低浏览器

  2. if you have detected leaks 如果你检测到泄漏

  3. if ED is a sufficient solution (often it is) 如果ED是一个充分的解决方案(通常是)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM