开发Vue的时候,我们可以做到那些力所能及的优化?

4,905 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

工作中,Vue 项目中可以做过哪些优化?

我们大部分的项目可能由架构师已经做好了处理,优化了打包速度、体积等。但是我们平常怎么在工作中,将我们做的那一部分工作进行优化呢?

v-ifv-show 的优化

v-ifv-show相信我们在平常开发中非常经常遇到,那么基于这两个命令,我们该如何选择,如何进行优化?首先,我们先明白 v-ifv-show 的区别。

v-if

  • v-if 在切换当中会对当前的判断模块进行销毁与重建条件块内的事件监听器和子组件的动作。
  • v-if 也是惰性的
    • 为什么这么说?因为如果当前条件为假的情况下,并不会执行该模块,在下次条件为真的情况下才会执行(会缓存当前的执行结果)

v-show

相比v-ifv-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。

区别

  • v-if 组件销毁/重建
  • v-show 组件隐藏(切换 CSS display

在我们切换v-if的时候,切换的模块中也可能包括数据绑定或子组,会让Vue产生有局部编译或者卸载动作,所以一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

v-ifv-show的建议使用场景

  • 一般情况下使用 v-if 即可,普通组件的销毁、渲染不会造成性能问题
  • 如果切换频率相当高或该模块大量计算,或者大量渲染,那么建议使用v-show

v-for 使用 key

key 可以优化内部的 diff 算法。注意,遍历数组时 key 不要使用 index

<ul>
    <!-- 遍历数组时 `key` 不要使用 `index`! -->
    <li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>

computed 缓存

ps: 关于Vue 的计算属性真的会缓存吗?,可以看看这个大佬的文章Vue 的计算属性真的会缓存吗?

computed 可以缓存计算结果,data 不变则缓存不失效。

<div id="app"> 
    <span @click="change">{{ userInfo }}</span> 
 </div>
export default {
     data() {
      return {
        name: '张三',
        age: 1
      }
    },
    methods: {
      change() {
        this.age ++
      },
    },
    computed: {
        // 未读消息的数量
        userInfo() {
            return `大家好,这是${this.name},今年${this.age}岁`
        }
    }
}

keep-alive

  • <keep-alive>用来对组件进行缓存,从而节省性能
  • <keep-alive> 可以通过 activateddeactivated 生命周期监听是否显示状态
  • <keep-alive> 可以通过includeexclude属性选择是否需要保存该组件

场景

  • 局部频繁切换的组件,如 tabs
    • 但是,其实如果这个页面组件所在的tab不处于激活状态,不是白白浪费资源了吗,个人任务这个的优化这其实也是互相相对的
  • 不可乱用 <keep-alive> ,缓存太多会占用大量内存,而且出问题不好 debug
    • 因为通过keep-alive缓存的页面,还要考虑在什么时机下刷新的问题。

异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。

场景

可以将大型的应用分割成小一些的代码块,只在需要的时候才从服务器加载。

  • 保证代码可以在需要时异步加载,不需要时不加载
  • 减少 main 包的体积,页面首次加载更快

vue3 使用 defineAsyncComponent 加载异步组件

路由懒加载

将不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件。类似异步组件。

场景

对于一些组件提交比较大的路由,我们就可以使用路由懒加载。

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // 路由懒加载
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

SSR

SSR 让网页访问速度更快,对 SEO 友好,但使用和调试成本高

总结

我们平常在工作中,可以将我们做的那一部分工作进行如下优化呢!

  • v-if 和 v-show
  • v-for 使用 key
  • computed 缓存
  • keep-alive
  • 异步组件
  • 路由懒加载
  • SSR