前言
前端经常需要和DOM打交道,增加、删除、替换是常见的DOM操作,然而就是这些操作时常成为网站性能的瓶颈,为了提高我们的网站性能,我们需要在DOM上面花不少心思。
1. 使用DOM的引用
在进行DOM操作前,我们先要对元素进行查找,或者需要根据后台返回的数据动态的创建元素,比如我们得到一个数组类型的数据data,需求是根据data往一个id为main的元素中添加li。我们可能会进行下面的DOM操作
|
|
上面的代码每次循环都会去计算一个data的length值,查询并得到main元素,可想而之其效率应该有多低下,好的方式是在进行循环之前便将data的length以及main元素缓存下来,在循环的时候使用其引用即可。
|
|
注意元素的查找默认根元素是document,当我们需要对某些元素进行频繁的查找的时候,可以先将某个元素缓存下来,后面的元素查找则是基于该元素,从而减短查找路径
2. 使用文档碎片
上面的操作中还有一个非常耗费性能的地方,
oMain.appendChild(li)
,每次循环都会进行一次元素添加操作,进而导致浏览器重排,我们知道浏览器的重排和重绘是需要耗费大量的时间进行的,所以提高网页性能的一方面是考虑尽量减少重排和重绘的次数。将频繁的DOM操作先在内存中完成,最后一次性将节点推进页面当中,这里我们会用到一个方法document.createDocumentFragment
,重新修改上诉例子如下
|
|
3. 使用innerHTML一次性添加DOM节点
以上的代码中每次都要通过
document.createElement('li')
创建元素,通过li.innerText = data[i]
设置文本信息,蛋疼的很,我们可以尝试着使用innerHTML来一次性添加元素,当然前提是你要先以字符串的形式把元素和数据拼接好
|
|
虽然这样做效率有所提升,但是当页面的DOM结构一旦复杂起来,拼接字符串便会变成一件相当恶心的事情
4. 使用事件代理批量处理事件
事件代理本质上就是将原本自己该干的事情,委托给别人( 这里是指父节点或者祖先节点 )做。
还是用上面的例子,假设我们现在要给每个li都添加上一个点击事件,可能会写出下面的代码
|
|
很显然data的lenth有多大,循环就得执行多少次addEventListener这个函数多少次,当数据量很大的时候效率自然低了不少,所以我们可以尝试使用事件代理的形式将事件委托到main元素上
|
|
5. 通过className来批量修改元素样式
经常有这样的场景,我们需要在js中批量的修改元素的样式,比如
|
|
以上代码会多次出发浏览器重绘和重排,一种好的方式是将需要修改的样式在样式文件中先写好,通过给元素赋值className的形式批量修改样式
|
|
给元素赋值className
|
|