关于javascript性能优化

本文介绍JavaScript DOM操作的性能优化技巧,包括批量增加DOM时使用innerHTML而非appendChild,创建和删除DOM节点的最佳实践,以及如何有效利用事件监听提高效率。

关于javascript性能优化注意些节。记录一下。

1. 批量增加Dom

尽量使用修改innerHTML的方式而不是用appendChild的方式; 因为使用innerHTML开销更小,速度更快,同时也更加内存安全.

有一点需要注意的是,innerHTML方式添加时,一定不要在循环中使用 innerHTML += 的方式添加,这样反而会使速度减慢; 而是应该中间用array缓存起来,循环结束后调用 xx.innerHTML = array.join(‘’);的方式,或者至少保存到string中再插到innerHTML.

针对用户列表一块采用这种方式优化后,加载速度提升一倍.

2. 单个增加Dom

这里是指要将新节点加载到一个内容不断变化的节点的情形,对于内容稳定的节点来说,随便怎么加都没有问题. 但是对于有动态内容的节点来说,为其添加子节点尽量使用 dom append的方式.

这是因为,dom append不会影响到其他的节点;而如果修改innerHTML属性的话,该父节点的所有子节点都会从dom树中剥离,再根据新的innerHTML值来重绘子节点dom;所有注册到原来子节点的事件也会失效.

综上,如果在一个有动态内容的节点上 出现了 innerHTML += 的代码,就该考虑是否有问题了.

3. 创建Dom节点

createElement方式创建一个dom节点,有一个很重要的细节: 在执行完createElement代码之后,应该马上appenddom树中; 否则,如果在将这个孤立节点加载到dom树之前所做的赋值它的属性和innerHTML的操作都会引发该dom片段内存无法回收的问题. 这个不起眼细节,一旦遇到大量dom增删操作,就会引发内存的灾难.

4. 删除Dom节点

删除dom节点之前,一定要删除注册在该节点上的事件,不管是用observe方式还是用attachEvent方式注册的事件,否则将会产生无法回收的内存.

,removeChildinnerHTML=’’二者之间,尽量选择后者. 因为在sIEve(内存泄露监测工具)中监测的结果是用removeChild无法有效地释放dom节点.

5. 创建事件监听

现有的js库都采用observe方式来创建事件监听,其实现上隔离了dom对象和事件处理函数之间的循环引用,所以应该尽量采用这种方式来创建事件监听.

6. 监听动态元素

Dom事件默认是向上冒泡的,发生在子节点中的事件,可以由父节点来处理. Event target/srcElement 仍是产生事件的最深层子节点. 这样,对于内容动态增加并且子节点都需要相同的事件处理函数的情况,可以把事件注册上提到父节点上,这样就不需要为每个子节点注册事件监听了.

同时,这样做也避免了产生无法回收的内存.即使是用Prototypeobserve方式注册事件并在删除节点前调用stopObserving,也会产生出少量无法回收的内存,所以应该尽量少的为dom节点注册事件监听.

所以,当代码中出现在循环里注册事件时,也是我们该考虑事件上提机制的时候了.

7. HTML提纯

HTML提纯体现的是一种各负其责的思想. HTML只用来显示,尽量不出现和显示无关的属性.比如onclick事件,比如自定义的对象属性.

事件可以用前面的方法避免, 对象属性指的是这样的一种情景: 通常情况下,动态增加的内容都是有个对象和它对应,比如聊天室的用户列表,每个显示用户的dom节点都有一个user对象和它对应,这样在html,应该仅保留一个id属性和user对象对应,而其他的信息,则应通过user对象去获取.


    基于PrototypeJS,写了一个Dom生成器,以提供简单高效的HTML操作接口的语法和语义优化

1. 使用类似JSONML的格式(HTML in JSON)描述DOM结构,以补充HTML转义字符串的表达形式,规范格式中可支持以下HTML语义:

l 标签名

l 属性(标识符,类名,事件名,内联样式等)

注:事件名上注册的侦听函数将自动通过Event.observe方式添加

l 嵌套标签

格式规范可简单描述为:

{

tag:string,          // 元素的标记名,如果没有,默认为div

children|cn: string|Array|json,  // 子结点对应的json数组或字节点的html或单个json

html:string,          // 对应的html,如果有cnchildren属性就忽略

style:function|string|json,    // 元素的样式,可以是函数,字符串,json对象

cls:string,           // 元素的class属性的值

x:y              // x表示其他名字,y表示变量值、非空字符串

onXXX: function // on为首的属性是事件侦听器

}

一个具体的例子为:

var list = DomBuilder.append('my-div', {

tag : 'ul',

cls : 'my-list',

children : [

{

tag : 'li',

id : 'item1',

html : 'List Item 1',

onclick : function() {

alert('List Item1 Clicked')

}

},

{

tag : 'li',

id : 'item2',

html : 'List Item 2',

customattr : 'customValue'

}]

});

2. 在实际修改DOM结构时,提供两种方式可供调用者选择,以便应需使用:

l W3C标准DOM操作(appendChild, removeChild)方式

l 使用innerHTML,insertAdjacentHTML等的实效模式

一个具体例子为:

DomBuilder.useDom = true; //显示申明使用W3C Dom操作方式

3. 另外提供DOM节点的有效回收方法

var abandoned = DomBuilder.destroy(list); //DOM节点从文档中移除

 

来源地址:http://blog.youkuaiyun.com/iinel/archive/2008/12/04/3446039.aspx

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值