`

JavaScript优化小记

 
阅读更多

前段时间接到一个任务:对项目组的Web项目主画面进行性能优化。

画面情况是:监控设备数量200多台,画面每10秒钟查询并更新数据,如果不对比缓存每10s进行更新,那么在IE浏览器下15分钟不到增长了88MB(用F12内存工具查看),而且会一直增长,直至浏览器崩溃...

以JS生成的html代码主要结构如下(填入HTML上的DIV标签内,$('').html(...)):

 

<ul >
<li><a><img /></a><div></div></li>
<li><a><img /></a><div></div></li>
...
<li><a><img /></a><div></div></li>
<ul>



网上找了sIEve工具对web页面进行了分析,

结论是:

1,每10秒钟内存会增加1MB多但是释放的不过十几KB,js循环中大量DOM节点建立(UL,内部包括LI/DIV/A节点),但是从未释放,以至内存占用曲线就是上升直线,DOM对象曲线中观察DOM数量也是不停增加。最主要的是js中建立的UL元素始终是orphan(孤立)节点。

2,每10秒钟为画面中的一组checkbox绑定一次jquery.ui.button操作,每次都生成了很多DIV /SPANdom对象,都是孤立节点,占用的内存始终没被浏览器释放;

于是,针对结论1写了个函数准备每次重画UL列表前主动清除内部节点包括UL标签本身:

 

	var releasememory3 = function(obj){		

		$(obj).find("a").unbind();
		$(obj).find("li").unbind();
		$("#rightmenu ul > li").unbind();

		var li0 = $(obj).find("li").eq(0);		
		removeLIAllsibling(li0);
		li0 = null;			
	}
	var removeLIAllsibling = function(_elem){//
		var _parentElement = _elem.parentNode;
		if(_parentElement){
			
			for (var i=0;i<_parentElement.childNodes.length;i++){
				 var childNode = _parentElement.childNodes[0];  // li
				                            
				 var div0 = childNode.getElementsByTagName("DIV");//div
				 for(var j=0;j<div0.length;j++){//div
					 div0[j].innerHTML = '';
					 childNode.removeChild(div0[0]);
				 }
				 div0= null;
				 
				 var a0 =  childNode.getElementsByTagName("A");//A
				 for(var k=0;k<a0.length;k++){//A					 
					 var img0 = a0[k].getElementsByTagName("IMG");//IMG
					 for(var m=0;m<img0.length;m++){
						 a0[k].removeChild(img0[0]);
					 }
					 img0 = null;
					 a0[0].onclick = null;
					 childNode.removeChild(a0[0]);
				 }
				 a0 = null;				 	
				 childNode.onclick = null;
				 _parentElement.removeChild(childNode);
			}
      	}
		_parentElement = null;
	};


测试结果是此releasememory3函数成功清除了孤立节点IMG/DIV/A/LI,但是无法清除UL节点。

 

 

由于js建立的UL标签始终是孤立节点,故把ul放在JSP的html部分,在js中仅仅生成li节点;

再次测试清除,IMG/DIV/A/LI都可以释放;

从sIEve测试结果看这样改写后的LI/A/DIV/IMG节点都不再是孤立节点每次更新HTML DIV中的ul内部节点都可以被浏览器释放。结论1的问题解决。

 

针对结论2,由于循环不断给html画面上的input控件绑定juery.ui.button操作,查看jquery.ui.button.js库文件,确实每次都会建立span对象并绑定很多事件,这部分不属于画面代码,比较难以主动清除,所以,解决办法是只作一次jquery.ui.button的绑定操作,循环中只更新input label标签中的变化内容text属性。问题2解决。

 

比较明显的2个内存泄露问题解决。

 

列举问题可能的原因:

 

1, Js代码DOM孤立节点、

2, js全局变量滞留内存、

3, js代码DOM对象注册匿名函数闭包导致的循环引用、

4, js对象dom对象相互引用导致内存不释放、

5,一般 js闭包导致的循环引用导致内存不释放、

6, js隐式对象转换导致的对象创建不释放、

7, js中DOM节点增加顺序错误导致内存不释放、

8, js大量循环重复重写同一对象属性(新建很多对象不释放)

9, DOM对象绑定事件未清除(可能在引用库比较多)

10,卸载页面时直接解绑事件、删除全局变量(无法解决页面不跳转时的内存增长,解决画面切换时的内存增长)

 

引用其他经验者的一段启发性文字:

 

 IE下的内存泄露原因就是循环引用,IE的垃圾回收器不能很好处理这种引用。 
会产生泄露的循环引用,只有孤立的DOM对象(脱离DOM树)。 
孤立的DOM对象间的循环引用,孤立的DOM对象与JS对象的循环引用。 
为什么是孤立的DOM对象呢?在离开页面时(刷新,跳转)会删除整个DOM树,在DOM树上的对象也会被删除,就算有循环引用,此时被打断。 
孤立的DOM对象有:一、用JS创建但未加入DOM树。二、从DOM树中删除的。 
所以避免泄露,就尽量不要让这样的DOM对象产生。 
有时候这样对象又不可避免,那就不要让这样对像产生循环引用。 
最常见的循环引用是由闭包产生,其执行环境中的变量(包括参数)引用了DOM对象。



 

 

 

 

分享到:
评论

相关推荐

    详解Vue SPA项目优化小记

    Vue 单页应用(SPA)优化是一项至关重要的工作,尤其是在现代 web 开发中,为了提供更好的用户体验,我们需要尽可能减少页面加载时间和提高性能。本文将详细介绍在 Vue 项目中进行优化的一些关键策略。 首先,我们...

    树形菜单DTree使用小记

    4. **优化性能**:通过缓存、懒加载等技术优化DTree在大数据量下的性能。 在实际项目中,TestDTree可能是一个测试用例或者示例代码,用于演示DTree的正确使用和功能验证。开发者可以通过阅读和运行这些代码,更好地...

    J2EE开发之常用开源项目小记

    这篇小记主要关注了几个关键领域:持久层、MVC框架、视图层、JavaScript库以及缓存技术。下面将详细阐述这些知识点。 1. **持久层**: - **Hibernate**:是一个流行的ORM(对象关系映射)框架,允许开发者以面向...

    js 正则学习小记之匹配字符串字面量优化篇

    JavaScript正则表达式是用于文本匹配的强大工具,它允许我们在文本中搜索特定的模式。在处理匹配字符串字面量时,正则表达式可以用来识别双引号内的文本内容。在提供的文章中,作者讨论了关于匹配字符串字面量的正则...

    node-v12.17.0-x64.7z

    v12.x系列的更新主要是性能优化、错误修复以及对ES模块和HTTP/2等特性的增强。 Node.js的核心特性包括: 1. V8引擎:Node.js使用Google的V8 JavaScript引擎,使得JS代码能以接近原生的速度运行。 2. 非阻塞I/O:...

    mysql-shell-8.0.20-macos10.15-x86-64bit.tar.7z

    MySQL Shell是MySQL数据库管理系统的一个重要组件,主要用于交互式地执行SQL命令、JavaScript脚本和Python脚本,提供了一个全面的接口来管理和操作MySQL服务器。在本案例中,我们讨论的是MySQL Shell的8.0.20版本,...

    node-v12.17.0.7z

    描述中提到的"macos node-v12.17.0.7z"表明这个Node.js的版本是专门为macOS操作系统编译和优化的。macOS是苹果公司为其硬件产品如Mac电脑提供的操作系统,它具有用户友好的图形界面和强大的命令行工具。在macOS上...

    flexpaper源码下载

    2. **FlexPaper使用小记.mht**:这可能是一个关于如何使用Flexpaper的教程或笔记,MHT是一种单个文件的网页归档格式,包含了网页的所有内容。 3. **bi.pdf**和**bi.swf**:这两个文件可能是示例文档,用来测试...

    Dislay分页

    3. **性能优化**:DisplayTag设计时考虑了性能问题,只加载当前页的数据,减少服务器负载。 4. **功能丰富**:除了分页,还包括列排序、筛选、导出(如CSV、PDF、Excel)等实用功能。 5. **兼容性**:DisplayTag与...

    IIS整合tomcat6图文教程

    在很多情况下,IIS作为前端服务器,可以处理HTTP请求,提供静态资源(如HTML、CSS、JavaScript等),而Tomcat则作为一个应用服务器,负责运行Java Web应用程序。这种结合方式可以充分利用IIS的高并发性能和Tomcat对...

    EditPlus 3.0

    综上所述,EditPlus 3.0作为一个强大的编辑器,其丰富的功能和对JAVA的优化使其成为开发者的重要工具。无论是编写代码、调试程序还是管理项目,EditPlus都能提供高效便捷的解决方案。通过不断迭代和更新,EditPlus...

Global site tag (gtag.js) - Google Analytics