现在的位置: 首页 > 综合 > 正文

JavaScript针对Dom相关的优化心得

2013年01月06日 ⁄ 综合 ⁄ 共 2455字 ⁄ 字号 评论关闭

组内同时总结的关于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

代码之后
,

应该马上
append


dom

树中
;

否则
,

如果在将这个孤立节点加载到
dom

树之前所做的赋值它的属性和
innerHTML

的操作都会引发该
dom

片段内存无法回收的问题
.

这个不起眼细节
,

一旦遇到大量
dom

增删操作
,

就会引发内存的灾难
.

4.




删除

Dom


节点


删除
dom

节点之前
,

一定要删除注册在该节点上的事件
,

不管是用
observe

方式还是用
attachEvent

方式注册的事件
,

否则将会产生无法回收的内存
.


,


removeChild


innerHTML=’’

二者之间
,

尽量选择后者
.

因为在
sIEve(

内存泄露监测工具
)

中监测的结果是用
removeChild

无法有效地释放
dom

节点
.

5.




创建事件监听


现有的
js

库都采用
observe

方式来创建事件监听
,

其实现上隔离了
dom

对象和事件处理函数之间的循环引用
,

所以应该尽量采用这种方式来创建事件监听
.

6.




监听动态元素


Dom

事件默认是向上冒泡的
,

发生在子节点中的事件
,

可以由父节点来处理
. Event


target/srcElement

仍是产生事件的最深层子节点
.

这样
,

对于内容动态增加并且子节点都需要相同的事件处理函数的情况
,

可以把事件注册上提到父节点上
,

这样就不需要为每个子节点注册事件监听了
.

同时
,

这样做也避免了产生无法回收的内存
.

即使是用
Prototype


observe

方式注册事件并在删除节点前调用
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

,如果有
cn


children

属性就忽略

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
节点从文档中移除

抱歉!评论已关闭.