首页 > 代码库 > DOM操作的性能优化

DOM操作的性能优化

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #454545 } span.s1 { font: 12.0px Helvetica }</style>

DOM操作的真正问题在于 每次操作都会出发布局的改变、DOM树的修改和渲染。

React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲。

所以关于DOM操作的性能优化主要包括:

1.查找元素的优化

2.尽量避免或减少改变DOM(比如添加,修改,删除DOM)

3.减少改变DOM的样式类

4.批量修改DOM

5.减少Iframe

6.样式放在header中,脚本放在关闭标签</body>之前

7.就是我刚才所说的大名鼎鼎的Virtual DOM

 

1.查找元素的优化

查找元素尽量使用ID,因为ID是唯一的,查找起来也是最快的。其次是根据类和类型查找元素,通过属性查找元素是最慢的。

 

 

2.尽量避免或减少改变DOM(比如添加,修改,删除DOM)

改变DOM就会引起浏览器渲染,而且渲染是相当慢的,应米面不必要的渲染

例如:

divUpdate.innerHTML = "";  
for ( var i=0; i<100; i++ )  
{  
 divUpdate.innerHTML += "<SPAN>This is a slower method! </SPAN>";  
}  

改为

var str="";  
 for ( var i=0; i<100; i++ )  
 {  
  str += "<SPAN>This is faster because it uses a string! </SPAN>";  
 }  
 divUpdate.innerHTML = str;  

  

3.减少改变DOM的样式类

 改变DOM元素的样式,类也会导致浏览器渲染,因此也应该减少不必要的操作

例如:

 var el = document.getElementById(‘mydiv‘);   
el.style.borderLeft = ‘1px‘;   
el.style.borderRight = ‘2px‘;   
el.style.padding = ‘5px‘;   

改为:

var el = document.getElementById(‘mydiv‘);   
l.style.cssText = ‘border-left: 1px; border-right: 2px; padding: 5px;‘;   

  

4.批量修改DOM

从文档流中先摘除该元素,对其应用多重改变,再将元素带回文档中,这样可以最小化重绘和重排。

具体方法:

1、隐藏元素,集中修改,然后再显示它

2、讲原始元素拷贝到一个脱离文档流的结点中,修改副本,然后覆盖原始元素

 

 

5.减少Iframe

iframe需要消耗大量的时间,并阻塞下载,建议少用

据说动态地给iframe添加url可以改善性能,未做测试

 

 

6.样式放在header中,脚本放在关闭标签</body>之前

样式放在header中,可以加快渲染,脚本放在关闭标签</body>之前可以加快下载速度,避免阻塞下载。

 

 

7.大名鼎鼎的Virtual DOM

Virtual DOM的核心思想是:批量操作DOM和作用最少的diff

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #454545 } span.s1 { font: 12.0px Helvetica }</style>

你一个接一个地去修改30个节点的时候,就会引起30次(潜在的)布局重算,30次(潜在的)重绘,等等。

之后,一旦你要把这些改动传递给真实DOM之前所有的改动就会整合成一次DOM操作。这一次DOM操作引起的布局计算和重绘可能会更大,但是相比而言,整合起来的改动只做一次,减少了(多次)计算。

这就是所谓的Virtual DOM算法,包括几个步骤:

1.用javascript对象结构表示DOM树的结构,然后用这个树构建一个真正的DOM树,插入到文档流中

2.当文档变更时,重新构造一颗新的对象树,然后用新的对象树和旧的对象树对比,记录两棵树的差异

3.把2所记录的差异应用到1所构建的真正的DOM树上,就实现变更了

 

Virtual DOM本质上就是在JS和DOM之间做了一个缓存。可以类比CPU和硬盘,既然硬盘这么慢,我们就在他们之间加一个缓存。既然JS这么慢,我们就在JS和DOM之间加一个缓存。CPU只操作内存,最后把变更写入硬盘。JS只操作Virtual DOM,最后把变更写入DOM。

 

其思想的关键是:

1.相对于 DOM 对象,原生的JS对象处理起来更快更简单

2.比较两棵DOM树的差异是 Virtual DOM算法最核心的部分,这也是所谓的Vritual DOM的diff算法 

 

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #454545 } span.s1 { font: 12.0px Helvetica }</style>

为什么快很多?

当然如果真的这样大面积的操作 DOM,性能会是一个很大的问题,所以 React 实现了一个虚拟 DOM,组件 DOM 结构就是映射到这个虚拟 DOM 上,React 在这个虚拟 DOM 上实现了一个 diff 算法,当要更新组件的时候,会通过 diff 寻找到要变更的 DOM 节点,再把这个修改更新到浏览器实际的 DOM 节点上,所以实际上不是真的渲染整个 DOM 树。这个虚拟 DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多

 

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #454545 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545; min-height: 14.0px } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545 } span.s1 { font: 12.0px Helvetica } span.s2 { font: 12.0px "PingFang SC" }</style>

DOM操作的性能优化