Vue常用性能优化

时间:2020-11-14 13:08:31   收藏:0   阅读:22

Vue常用性能优化

Vue常用的一些优化方式,主要是在构建项目过程需要注意的方面。

编码优化

避免响应所有数据

不要将所有的数据都放到data中,data中的数据都会增加gettersetter,并且会收集watcher,这样还占内存,不需要响应式的数据我们可以直接定义在实例上。

<template>
    <view>

    </view>
</template>

<script>
    export default {
        components: {},
        data: () => ({
            
        }),
        beforeCreate: function(){
            this.timer = null;
        }
    }
</script>

<style scoped>
</style>

函数式组件

函数组是一个不包含状态和实例的组件,简单的说,就是组件不支持响应式,并且不能通过this关键字引用自己。因为函数式组件没有状态,所以它们不需要像Vue的响应式系统一样需要经过额外的初始化,这样就可以避免相关操作带来的性能消耗。当然函数式组件仍然会对相应的变化做出响应式改变,比如新传入新的props,但是在组件本身中,它无法知道数据何时发生了更改,因为它不维护自己的状态。很多场景非常适合使用函数式组件:

区分computed和watch使用场景

computed是计算属性,依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值。
watch更多的是观察的作用,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
当我们需要进行数值计算,并且依赖于其它数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时,都要重新计算。当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。

v-for添加key且避免同时使用v-if

区分v-if与v-show使用场景

长列表性能优化

Vue会通过Object.defineProperty对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要Vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,可以通过Object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。对于需要修改的长列表的优化大列表两个核心,一个分段一个区分,具体执行分为:仅渲染视窗可见的数据、进行函数节流、 减少驻留的VNodeVue组件,不使用显示的子组件slot方式,改为手动创建虚拟DOM来切断对象引用。

export default {
  data: () => ({
      users: {}
  }),
  async created() {
      const users = await axios.get("/api/users");
      this.users = Object.freeze(users);
  }
};

路由懒加载

Vue是单页面应用,可能会有很多的路由引入,这样使用webpcak打包后的文件很大,当进入首页时,加载的资源过多,页面会出现白屏的情况,不利于用户体验。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就更加高效。对于Vue路由懒加载的方式有Vue异步组件、动态importwebpack提供的require.ensure,最常用的就是动态import的方式。

{
  path: "/example",
  name: "example",
  //打包后,每个组件单独生成一个chunk文件
  component: () => import("@/views/example.vue")
}

服务端渲染SSR

如果需要优化首屏加载速度并且首屏加载速度是至关重要的点,那么就需要服务端渲染SSR,服务端渲染SSR其实是优缺点并行的,需要合理决定是否真的需要服务端渲染。

优点

缺点

使用keep-alive组件

当在组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能等问题,使用<keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。重新创建动态组件的行为通常是非常有用的,但是在有些情况下我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来,此时使用<keep-alive>包裹组件即可缓存当前组件实例,将组件缓存到内存,用于保留组件状态或避免重新渲染,和<transition>相似它,其自身不会渲染一个DOM元素,也不会出现在组件的父组件链中。

<keep-alive>
    <component v-bind:is="currentComponent" class="tab"></component>
</keep-alive>

打包优化

模板预编译

当使用DOM内模板或JavaScript内的字符串模板时,模板会在运行时被编译为渲染函数,通常情况下这个过程已经足够快了,但对性能敏感的应用还是最好避免这种用法。预编译模板最简单的方式就是使用单文件组件——相关的构建设置会自动把预编译处理好,所以构建好的代码已经包含了编译出来的渲染函数而不是原始的模板字符串。如果使用webpack,并且喜欢分离JavaScript和模板文件,可以使用vue-template-loader,其可以在构建过程中把模板文件转换成为JavaScript渲染函数。

SourceMap

在项目进行打包后,会将开发中的多个文件代码打包到一个文件中,并且经过压缩、去掉多余的空格、babel编译化后,最终将编译得到的代码会用于线上环境,那么这样处理后的代码和源代码会有很大的差别,当有bug的时候,我们只能定位到压缩处理后的代码位置,无法定位到开发环境中的代码,对于开发来说不好调式定位问题,因此sourceMap出现了,它就是为了解决不好调式代码问题的,在线上环境则需要关闭sourceMap

配置splitChunksPlugins

Webpack内置了专门用于提取多个Chunk中的公共部分的插件CommonsChunkPlugin,是用于提取公共代码的工具,CommonsChunkPlugin4.0及以后被移除,使用SplitChunksPlugin替代。

使用treeShaking

tree shaking是一个术语,通常用于描述移除JavaScript上下文中的未引用代码dead-code,其依赖于ES2015模块系统中的静态结构特性,例如importexport,这个术语和概念实际上是兴起于ES2015模块打包工具rollup

第三方插件的按需引入

我们在项目中经常会需要引入第三方插件,如果我们直接引入整个插件,会导致项目的体积太大,我们可以借助babel-plugin-component,然后可以只引入需要的组件,以达到减小项目体积的目的,以项目中引入element-ui组件库为例。

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

import Vue from ‘vue‘;
import { Button, Select } from ‘element-ui‘;

Vue.use(Button)
Vue.use(Select)

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://zhuanlan.zhihu.com/p/121000054
https://www.jianshu.com/p/f372d0e3de80
https://juejin.im/post/6844903887787278349
https://juejin.im/post/6844904189999448071
https://www.lagou.com/lgeduarticle/22278.html
https://www.cnblogs.com/mmzuo-798/p/11778044.html
https://blog.csdn.net/gtlbtnq9mr3/article/details/104889927

原文:https://www.cnblogs.com/WindrunnerMax/p/13972793.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!