虚拟DOM的性能

虚拟DOM的性能

前文说到,声明式代码的更新性能消耗:找出差异的性能消耗+直接修改的性能消耗,so,如果我们能够最小化找出差异的性能消耗,就可以让声明式代码的性能无限接近于命令式代码的性能。而这里所说的虚拟DOM,正是为了最小化找出差异这一步的性能消耗。

到这,我们得出一个结论,就是,采用虚拟DOM的更新技术,在理论上不可能比原生Javascript操作DOM更好。那么虚拟DOM的要解决的问题就出来了:让我们使用声明式的代码,还能够保证程序的性能下限,让应用程序的性能不至于太差

第一个问题

为了比较innerHTML和虚拟DOM的性能,我嫩首先要了解他们创建、更新页面的过程。

对于innerHTML来说,为了创建页面,我们需要构造如下HTML字符串:

第一步

 const html = `
<div><span>...</span></div>
 `

第二步

 div.innerHTML = html

为了渲染出一个页面,首先要把字符串解析成了DOM树,这是一个涉及DOM的计算,因此,它的性能消耗远比Javascript大的多。

根据上述两步得出一个公式:innerHTML 创建页面的性能:HTML 字符串拼接的计算量 + innerHTML 的 DOM计算量。

第二个问题(虚拟DOM创建项目的消耗)

第一步
创建 JavaScript 对象,这个对象可以理解为真实 DOM 的描述;

第二步
是递归地遍历虚拟 DOM 树并创建真实 DOM。

同样,根据上述步骤得出一个公式: 虚拟DOM创建页面的性能:创建 JavaScript 对象的计算量 + 创建真实 DOM 的计算量

结论

可以看到,无论是纯 JavaScript 层面的计算,还是 DOM 层面的计算,其实两者差距不大。这里我们从宏观的角度只看数量级上的差异。如果在同一个数量级,则认为没有差异。在创建页面的时候,都需要新建所有 DOM 元素。

那么在差异很大的层面,两者的性能消耗会不会有所不同呢?

分析:
使用innerHTML更新页面的的过程是**重新构建HTML字符串,再重新设置DOM元素的innerHTML属性,**那么这样将来,即使是我仅仅更新了一个元素中的一个文字,就等价于 销毁所有的DOM元素,再全面的去创建新的DOM
反观使用虚拟DOM进行修改元素,只需要比较新旧DOM节点中不同之处,并更新它。

由此可以看出,虚拟DOM在Javascript层面需要比创建页面多出一个Diff算法,但是缺省下了整个DOM销毁与创建的过程。毕竟Diff算法也是执行在Javascript层面的,相较于DOM层面的计算会减小很多心智负担。到这里可能你还会有人讲,innerHTML的性能还是有可能优于虚拟DOM,那么,如果页面的元素数量级很高,如果还采取DOM销毁与创建,性能定然没有虚拟DOM好!

结论

我们分了几个维度:心智负担、可维护性和性能。其中原生 DOM操作方法的心智负担最大,因为你要手动创建删除修改大量的DOM 元素。但它的性能是最高的,不过为了使其性能最佳,我们同样要承受巨大的心智负担。
最后,我们来看看虚拟 DOM,它是声明式的,因此心智负担小,可维护性强,性能虽然比不上极致优化的原生 JavaScript,但是在保证心智负担和可维护性的前提下相当不错。

思考(鱼与熊掌兼得)

有没有办法做到,既声明式地描述UI,又具备原生 JavaScript 的性能呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值