为什么经过大量网友测试,虚拟DOM比直接操作DOM效率高?
这是一个老生常谈的问题了,为此,许多前端大佬包括尤大大都在卖力的解释,作为一个菜鸟,我知道该如何表达能让大家解开困惑
首先,虚拟DOM是什么?
虚拟DOM是真实DOM的映射,是一个JS对象,是真实DOM的轻量级副本。
为什么需要虚拟DOM?
(先看看八股文:)
- 减少直接操作DOM的次数,提高性能
- 跨平台,除了浏览器,还可以在服务器端和原生应用中使用
虚拟DOM的优点
- 提高性能:虚拟DOM可以批量操作DOM,减少直接操作DOM的次数,提高性能
- 跨平台:虚拟DOM可以跨平台,除了浏览器,还可以在服务器端和原生应用中使用
- 易于调试:虚拟DOM可以方便地进行调试,可以方便地进行调试
- 易于测试:虚拟DOM可以方便地进行测试,可以方便地进行测试
(轮到我了)
虚拟DOM的诞生实际上是出现在声明式编程之后,是为了解决框架中大量DOM操作的问题。假设我们不存在虚拟DOM,但是你又想用简便的声明式编程开发,那会产生什么样的开发方式?参考如下代码:
// 假设我们不存在虚拟DOM
const state = {
isLoading: false,
}
Object.defineProperty(state, 'isLoading', {
get() {
return isLoading
},
set(newVal) {
isLoading = newVal
render()
}
})
function render(){
if(state.isLoading){
$0.innerHTML = 'loading'
}else{
$0.innerHTML = 'data'
}
}
这是举了一个声明式编程,但是没有虚拟DOM的例子,如果我们要用声明式编程开发,现在的loading是false,假设我们又执行state.isLoading = false,那么如果在没有虚拟DOM的情况下,那么$0.innerHTML = 'data'这段代码会被执行,这又是一次DOM操作,如果状态改变很多次,那么就会执行很多次DOM操作,这样性能是很低的。
看到一个很有意思的比喻
能放在前端的都放在前端。 一般去饭店、旅馆前,都会打电话问一下还有没有位子,避免白跑一趟。
在这个意义上,我们说打电话比跑一趟快。
可是打完电话后,你不还是得真的去一趟吗,对于住店而言,这个是省不了的。打电话的意义在于,五家店,你不用排着白跑,确定需要真的跑一趟了,才出门。换言之,跑一趟,只是对于确认有没有位子值得真的出门而言,才是可省的。
vue、react等的虚拟dom操作,就相当于打电话确认哪些更新真的发生了,值得进行真实dom操作。
因此,如果业务场景是全都需要更新,那打电话反倒成了额外的工作了。
之所以通常不必考虑这种可能性,原因有三:
1.几乎不可能全都需要更新
2.打电话就算浪费,开销也极为低廉,你有兴趣可以具体定量测试一下,我简单定性地打个比方,大概类似一百个店只要节省了一个白跑,九十九个电话就回本了
3.除了内容显示,前端现实业务往往还需要绑定onclick等交互事件,再加上双向绑定,直观、智能的模板语法是非常重要的,虚拟dom只是vue、react等的一部分,剩下的这些部分都是我们选择这些框架的重要原因,甚至才是根本原因