博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
innerHTML引起IE的内存泄漏
阅读量:7114 次
发布时间:2019-06-28

本文共 2110 字,大约阅读时间需要 7 分钟。

 

 

内存泄漏常见的原因有三种:

1. 闭包

2. 未解除事件绑定

3. 循环引用DOM元素

除此之外,还有一种泄漏原因少有人知,它和innerHTML有关,不过很容易解决。

出现这种内存泄漏需要有三个条件:

  1. 内存中存在一个未加入DOM树的元素

  2. 给这个元素设置innerHTML,注意,必须是能创建元素并且绑定了DOM 0级事件

  3. 必须在这个元素加入DOM树前设置它的innerHTML

 

举个例子:

// 创建一个仅存在于内存中的元素
var 
el = document.createElement(
'div'
);
// 设置innerHTML
el.innerHTML =
'<a onclick = "testFn()">Test Link</a>'
;
// 加入DOM树
document.body.appendChild(el)

 

这种写法很常见对吧,但你根本察觉不到有内存泄漏。唯一的隐患在于,当你在一个相同的页面上频繁地用这种方式设置innerHTML,一次又一次,反反复复,没完没了,好吧,其实也没那么多次,总之是很多次之后,就会出现问题了。

肯定有人会说,谁那么蛋疼地总折腾一个元素,其实在ajax泛滥的时代,经常需要动态更新页面,所以这种情况也并非罕见。

如果实在不信,这里有两个DEMO页面:

 

				IE innerHTML Memory Leak Demo												

IE innerHTML Memory Leak Demo

Upon clicking the "Start Leak" button, a script will execute repeatedly which creates a new

element in memory, sets its innerHTML to a string of 2000
tags with onclick events wired up ('
Test Link'), and then adds that
to the page.

Letting this script run for about 60 seconds, and using Perfmon to monitor memory consumption, you should notice a significant increase in the amount of memory consumed. To see the same script logic that doesn't leak memory, view the No Leak Page.

  

   

				IE innerHTML Memory Leak Demo (the fix)												

IE innerHTML Memory Leak Demo (the fix)

Upon clicking the "Start Leak" button, a script will execute repeatedly which creates a new

element in memory and then adds that element to the page. Only
after the element has been added to the page, do we set its .innerHTML to a string to 2000
tags with onclick events wired up ('
Test Link').

Letting this script run for about 60 seconds, and using Perfmon to monitor memory consumption, you should notice that, unlike the Leak Page, memory consumption remains relatively constant.

  

接着来看怎么解决它:

其实很简单,换个顺序,先把元素加入DOM树,再设置innerHTML。

当然你也可以完全放弃使用innerHTML,这样做好处多多,比如不会存在未解除事件绑定的情况,但貌似完全放弃innerHTML也不现实。。。

转载地址:http://nwwel.baihongyu.com/

你可能感兴趣的文章
Servlet的API(一)
查看>>
网络01:双无线路由器无缝对接设置
查看>>
实现Android和PC之间的蓝牙通信
查看>>
rails将类常量重构到数据库对应的表中之二
查看>>
微软面试题:写程序找出二叉树的深度
查看>>
[Google Guava] 1.2-前置条件
查看>>
OEA框架 2.9 Pre-Alpha 源码公布
查看>>
我的MYSQL学习心得(十三) 权限管理
查看>>
Spring Data —— 完全统一的API?
查看>>
[翻译] JTBorderDotAnimation
查看>>
浏览器兼容性小记-DOM篇(二)
查看>>
【Oracle】lsnrctl reload 命令简介
查看>>
091023 T GIX4 项目中的 智能部署 和 智能客户端
查看>>
Mondrian and OLAP
查看>>
【音乐分享】Let Me Go
查看>>
java写一个爬虫
查看>>
Drill官网文档翻译六:存储插件的注册
查看>>
poj 1502 单源最短路径
查看>>
CUDNN v3特性
查看>>
为什么C# md5 32位加密算法,密码明文会出现31位
查看>>