DOM操作的性能优化

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

你一个接一个地去修改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算法 

 

为什么快很多?

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

 

posted @ 2017-03-21 15:01  张三的美丽家园  阅读(1075)  评论(0编辑  收藏  举报