首页 > 代码库 > DOM操作的性能优化
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
<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操作的性能优化