使用innerHTML和outerHTML而带来的内存和性能问题
在删除带有事件处理程序或引用了其他JavaScript对象子树时,就有可能导致内存占用问题。假设某个元素有一个事件处理程序(或者引用了一个JavaScript对象作为属性),在使用innerHTML、outerHTML属性和insertAdjacentHTML()方法将该元素从文档树中删除后,元素与事件处理程序(或JavaScript对象)之间的绑定关系在内存中并没有一并删除。如果这种情况频繁出现,页面占用的内存数量就会明显增加。因此,在使用innerHTML、outerHTML属性和insertAdjacentHTML()方法时,最好先手工删除要被替换的元素的所有事件处理程序和JavaScript对象属性。
不过,使用这几个属性-特别是使用innerHTML,仍然还是可以为我们提供很多便利的。一般来说,在插入大量新HTML标记时,使用innerHTML属性与通过多次DOM操作先创建节点再指定他们之间的关系相比,效率要高得多。这是因为在设置innerHTML或outerHTML时,就会创建一个HTML解析器。这个解析器是在浏览器级别的代码(通常是C++编写的)基础上运行的,因此比执行JavaScript快得多。不可避免地,创建和销毁HTML解析器也会带来性能损失,所以最好能够将设置innerHTML、outerHTML的次数控制在合理的范围内。
例如,下列代码使用innerHTML创建了很多列表项:
for(var i=0; i<100; i++){
ul.innerHTML += "<li>"+ i + "</li>"; //要避免这种频繁操作!!!
}
这种每次循环都要设置一次innerHTML的做法效率很低。而且,每次循环还要从innerHTML中读取一次信息,就意味着每次循环要访问两次innerHTML。最好的做法是单独构建字符串,最后一次性地将结果字符串赋值给innerHTML,如下:
var itemsHtml = "";
for(var i=0; i<100; i++){
itemsHtml += "<li>"+ i +"</li>";
}
ul.innerHTML = itemsHtml ;
这个例子的效率要高很多,因为它只对innerHTML执行了一次赋值操作。