一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
本题类型:综合题、开放问题
本题难度:⭐ ⭐
答:
操作原生 JS 性能更好,理由如下:
因为比起操作原生 JS,操作虚拟 DOM 多了一步,虚拟 DOM 需要找到页面更新前后的差异,最终修改页面的时候还是要操作原生 JS。
假设把修改页面元素的性能消耗定义为 A,把找出页面元素的差异的性能消耗定义为 B
- 操作虚拟DOM的性能消耗为 A + B
- 直接修改页面元素的性能消耗为 A
A + B > A,很显然,使用原生 JS 的性能优于虚拟 DOM。
来看一个实例吧,假设有一个 div,它的文本内容为 'hello':
<div id='app'>hello</div>
现在要把这个 div 的文本内容改为 'hello1',使用原生 JS 可以这么操作。
const div = document.getElementById('app')
div.textContent = 'hello1'
还有比上面的代码性能更好的操作方式吗?答案是,没有,这就是最简单,性能最好的方式了。
如果我是用 Vue 来实现的这个功能:
<template>
<div> hello </div>
</template>
改为
<template>
<div> hello1 </div>
</template>
看似前后只有一个字符的差距,实际上在 Vue 内部,做了很多事情,比如:解析模板字符串、创建虚拟 DOM、通过 diff 算法比对等等,这些都是性能的损耗。
那为什么很多人都说虚拟 DOM 性能比原生 JS 更好呢?
那是因为很多人指的使用原生 JS 操作 DOM 是指 使用不当的原生 JS,比如:
- 只更新一小部分元素,却销毁所有旧的节点,再新建所有新的节点。
- 使用 innerHTML 替换节点。
记住这个结论:并不是原生 JS 性能不好,原生 JS 是性能最好的,操作不当的原生 JS 才会导致性能不好。
下面我们就以 innerHTML 为例,来具体分析一下为什么使用虚拟 DOM 比使用操作不当的原生 JS 性能更好。
<ul id="list"></ul>
const htmlStr = `
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
`
const ul = document.getElementById('list')
ul.innerHTML = htmlStr
如上代码所示,把 html 字符串赋值给一个元素,就实现了元素的创建。
因为 innerHTML 只能通过赋值重新设置,所以如果需要更改元素,比如把上面的 item1 变更为 item11,哪怕只是更改了一个字符,也需要销毁所有的旧的 DOM 元素,再全量创建新的 DOM 元素。
这里要明白一个概念:JS 层面的计算性能远好于 DOM 层面的计算,测试代码和结果如下:
console.time('js')
const arr = []
for(let i = 0; i < 100000; i++) {
const div = {
tag: 'div'
}
arr.push(div)
}
console.timeEnd('js')
console.time('dom')
const element = document.getElementById('element')
for(let i = 0; i < 100000; i++) {
const div = document.createElement('div')
element.appendChild(div)
}
console.timeEnd('dom')
有了这样的基础,我们用一张表格来对比一下在更新时虚拟 DOM 和 innerHTML 的性能差异:
| 虚拟DOM | innerHTML | |
|---|---|---|
| 纯 JS 运算 | 创建新的 VNode 对象 + diff | 渲染 HTML 字符串 |
| DOM 运算 | 更新有变化的 DOM | 销毁所有旧 DOM,再新建所有新 DOM 元素 |
| 性能因素 | 与数据变化量相关 | 与模板大小相关 |
使用虚拟 DOM,在 JS 层面会多一个 diff 算法的性能损耗,然而它毕竟也只是 JS 层面的计算,不会耗费太多时间。
但在 DOM 层面,虚拟 DOM 只会更新有变化的 DOM,而 innerHTML 需要全量更新,虚拟 DOM 的性能优势就体现出来了。
而且对于虚拟 DOM 来说,无论页面多大,只会更新变化的内容,但是对于 innerHTML,页面越大,性能的消耗就越大。
所以,使用操作不当的原生 JS,性能是远小于使用虚拟 DOM 的。
结尾
总结一下,使用虚拟 DOM 在可维护性和心智负担上都远优于使用原生 JS,在性能上也远优于操作不当的原生 JS。
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
本文参考:Vue.js设计与实现
上一篇:
下一篇: