前言
面对一个功能的实现是把分成几个组件,还是不分呢,这是个问题?对于是否要拆分,我列了些常见的理由如下:
- 更好的复用代码
- 降低组件的复杂度(毕竟没人想看几百行代码的组件)
- 测试更方便些
- ...
然而我想说的是,对于vue的组件来说,拆分组件可能会带来性能优化
一个问题
来看一个简单的组件(代码如下), 在input框输入数字1,页面会有什么样的变化?
<template>
<div>
<div>{{ curText }}</div>
<input type="text" v-model="curText" />
<div v-for="curItem in 100" :key="curItem">
{{ curItem }}
<div v-for="curItem1 in 50" :key="curItem1">
{{ curItem1 }}
<div v-for="curItem2 in 50" :key="curItem2">
{{ curItem2 }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
curText: "",
};
},
};
</script>
答案是会在页面显示出1, 完了??? 确实,但是出现1的过程确有些卡 (如下图所示)
上面这种情况出现卡顿,在分析原因之前,将这个组件进行拆分,过程如下
- 将上面页面中不改变的部分抽成一个单独组件
displayComponent.vue
<template>
<div>
<div v-for="curItem in 100" :key="curItem">
{{ curItem }}
<div v-for="curItem in 50" :key="curItem">
{{ curItem }}
<div v-for="curItem in 50" :key="curItem">
{{ curItem }}
</div>
</div>
</div>
</div>
</template>
原本代码则改成如下
<template>
<div>
<div>{{ curText }}</div>
<input type="text" v-model="curText" />
<display-componet></display-componet>
</div>
</template>
改完再次输入1时,就会发现卡的现象消失了(或者说好多了)!!!!!
简单的分析
通过对比两次的改动可以明显的发现
- 改动的地方只是将页面中不变的部分抽成了组件
- 整个页面的dom数据很多
那根据上面的例子和简单,很容易得出一个结论抽成一个组件(数据无依赖)对页面性能是有帮助的。同时也很容易产生一个疑问-》这个是为啥呢??
为了解决疑问,让我们看看在往input里输入数字,vue做了什么事
输入数字1 =》 ... 触发_update => patch => patchVnode => updateChidren ...
上面的写出的部分流程也就是耳熟能详的virtual dom diff部分过程 (关于diff算法及具体流程这里就不再赘述,有许多优秀文章讲解),在这个过程中可以发现updateChildren对于有没拆分组件有着巨大的差异:
| 拆成组件 | 不拆组件 | |
|---|---|---|
| updateChidren | 没有 | 会遍历检测所有子节点(重复patchVnode 步骤) |
当dom节点足够多的时候,遍历检测节点也就大量的时间消耗
结论
通过上述的例子,也就说明了有时候拆分成组件会带来性能的优化, 当然这不是绝对的,例如:有数据关联的父子组件 (以上的例子都是在vue 2.6的版本)
最后上述有任何不正确的地方,欢迎指出,感谢!!