Vue项目中的优化实战

366 阅读2分钟

开发Vue项目中的优化

我们都知道Vue的数据改变会触发视图的更新,Vue的视图更新会有diff算法对新旧的DOM节点进行比较,对比出修改的节点再进行视图的更新,在此过程中是有性能的消耗的,而且Vue的更新是以组件为最小单位的,因此组件越大越复杂的话,那么每次diff算法的性能消耗就会更大。

如果是不经常触发视图更新那么这些消耗多数情况下都还能接受,但是有些组件中可能会存在数据实时变化,这样的话就会经常触发视图的更新,对复杂组件来说性能消耗就是极大的了。

下面举一个例子先放图片:

1715626413769.png

1715626423205.png

<template>
    <div class="countdown-wrap">
        <div>倒计时:</div>
        <div>{{time}}</div>
    </div>
</template>

<script setup>
    import { ref, onUpdated } from 'vue'

    let time = ref(100)

    const fn = setInterval(() => {
        time.value-= 1
    }, 1000)

    onUpdated(() => { 
        console.log("数据更新")  
        if (time.value === 0) {
            clearInterval(fn)
        }
    })

</script>

上面是一个倒计时的案例,倒计时每秒钟会减1,可以看到每次响应式数据time发生改变,都会触发onUpdated生命周期,那么也会触发组件diff算法节点对比,然后再视图更新,像这种数据频繁改变触发试图更新的组件为了性能问题我们应该进行性能优化。

优化

针对上面问题,我们可以将频繁改变数据的功能点抽离成为一个小组件。

父组件

<template>
    <div class="countdown-wrap">
        <div>倒计时:</div>
        <time-cpt />
    </div>
</template>

<script setup>
    import TimeCpt from './Time.vue'
    import { ref, onUpdated } from 'vue'

    onUpdated(() => { 
        console.log("父组件数据更新")  
    })

</script>

子组件

<template>
    <div class="time">
        <div>{{time}}</div>
    </div>
</template>

<script setup>
    import { ref, onUpdated } from 'vue'

    const time = ref(100)
    
    const fn = setInterval(() => {
        time.value-= 1
    }, 1000)

    onUpdated(() => { 
        console.log("子组件数据更新")  
        if (time1.value === 0) {
            clearInterval(fn)
        }
    })
</script>

1715634856263.png

可以看到数据改变后触发子组件的onUpdated,而父组件的并没有触发,这样的话更新对比只会触发子组件的,因为子组件是一个比较简单的组件,因此消耗的性能会较小。

总结

因为越复杂的组件更新对比所需要消耗的性能更大,因此在开发中尽量将经常因数据改变而触发视图更新的功能点抽离成较小和较简单的子组件,这样可以避免复杂的父组件触发更新对比,转而触发较小的子组件的更新对比,从而起到优化的作用。

因为Vue2的diff算法性能不如Vue3,所以Vue2视图更新对比消耗的性能也更大,因此在Vue2中用此方法的优化更为明显。