vue 前端优化性能优化方法

1.列表使用唯一 key

  v-for="item in activeList" :key="item.id"

      原因是不使用 key 或者列表的 index 作为 key 的时候,每个元素对应的位置关系都是 index,直接导致我们插入的元素到后面的全部元素,对应的位置关系都发生了变更,所以在 patch 过程中会将它们全都执行更新操作,再重新渲染。这可不是我们想要的,我们希望的是渲染添加的那一个元素,其他四个元素不做任何变更,也就不要重新渲染。

2.使用 v-show 复用 DOM

<template>
  <div>
    <div v-show="status" class="on">
      <my-components />
    </div>
    <section v-show="!status" class="off">
      <my-components >
    </section>
  </div>
</template>

v-show:是渲染组件,然后改变组件的 display 为 block 或 none
v-if:是渲染或不渲染组件

原理就是使用 v-if 当条件变化的时候,触发 diff 更新,发现新旧 vnode 不一致,就会移除整个旧的 vnode,再重新创建新的 vnode,然后创建新的 my-components 组件,又会经历组件自身初始化,renderpatch 等过程,而 v-show 在条件变化的时候,新旧 vnode 是一致的,就不会执行移除创建等一系列流程

所以对于可以频繁改变条件的场景,就使用 v-show 节省性能,特别是 DOM 结构越复杂收益越大

不过它也有劣势,就是 v-show 在一开始的时候,所有分支内部的组件都会渲染,对应的生命周期钩子函数都会执行,而 v-if 只会加载判断条件命中的组件,所以需要根据不同场景使用合适的指令

 3. 变量本地化

原理:多次引用的变量保存起来,因为每次访问 this.xx 的时候,由于是响应式对象,所以每次都会触发 getter,然后执行依赖收集的相关代码,如果使用变量次数越多,性能自然就越差

从需求上说在一个函数里一个变量执行一次依赖收集就够了,可是很多人习惯性的在项目中大量写 this.xx,而忽略了 this.xx 背后做的事,就会导致性能问题了

var num = this.first;
var sum = this.sumNum;
for (let i = 0; i < 200; i++) {
    sum+= sum + num + i// 避免频繁引用 this.xx
 }

4. 第三方插件按需导入 

import Vue from 'vue';

import { Button, Select } from 'element-ui';

import App from './App.vue';

Vue.component(Button.name, Button);

Vue.component(Select.name, Select); /* 或写为 *

Vue.use(Button) *

Vue.use(Select) */

new Vue({ el: '#app', render: h => h(App) });

5.路由懒加载

没有用路由懒加载

import Vue from 'vue'

import Router from 'vue-router'

const CPKB1 = () => import('@/views/centit/CPKB1') 

const CK = () => import('@/views/centit/CK')  //首页

export default new Router({

  // mode: 'history', //打包的时候关闭

  //saveScrollPostioin: true,

  scrollBehavior(to, from, savedPosition) {

    if (savedPosition) {

      return savedPosition

    } else {

      return {

        x: 0,

        y: 0

      }

    }

  },

  base:'/RAW/dist',  //包名 一级目录和文件名一致 打包的时候打开

  linkActiveClass: 'active',

  routes: [

    {

      path:'/',

      name:'CK',

      component:CK,

      mete:{title:'出库看板'},

      children: [

        {

          path:'/CPKB1',

          name:'CPKB1',

          component:CPKB1,

          mete:{title:'CPKB1'}

        }

      ]

    },

  ]

})

用了路由懒加载:

const router = new Router({
  routes: [
    { path: '/CPKB', component: () => import('@/views/centit/CPKB1') },
    { path: '/CK', component: require('@/views/centit/CK').default }
  ]
})

在进入这个路由的时候才会走对应的 component,然后运行 import 编译加载组件,可以理解为 Promise 的 resolve 机制

  • import:Es6语法规范、编译时调用、是解构过程、不支持变量函数等
  • require:AMD规范、运行时调用、是赋值过程,支持变量计算函数等

6. keep-alive缓存页面

<template>
  <div id="app">
    <keep-alive include="['CPKB1','CPKB2']">
        <router-view></router-view>
    </keep-alive>
   </div>
</template>

我们都可以通过内置组件 <keep-alive></keep-alive> 来把组件缓存起来,在组件切换的时候不进行卸载,这样当再次返回的时候,就能从缓存中快速渲染,而不是重新渲染,以节省性能

7. 事件的销毁 

<script>
export default {
    created() {
      this.timer = setInterval(this.load, 1000)
      addEventListener('touch', this.touch, false)
    },
    beforeDestroy() {
      clearInterval(this.timer)
      this.timer = null
      removeEventListener('touch', this.touch, false)
    }
}
</script>

  Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件而对于定时器,addEventListener 注册的监听器等,就需要在组件销毁的生命周期钩子中手动销毁或解绑,以避免内存泄露.

8.项目图片懒加载

  使用第三方图片懒加载库

9.长列表性能优化

针对只用于展示的数据,可以使用Object.freeze来处理。

原因如下:Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 Vue 劫持我们的数据呢?可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

export default {  

   data: () => ({   

       users: {}  

}),  

async created() {    

    const users = await axios.get("/api/users");    

    this.users = Object.freeze(users);  

} };

 10.vue 组件中的 data 是函数而不是对象

使用这种函数方式

export default {

    name: 'app',

    data() {

        return {

            level:''1"

        };

    },

}

不使用这种对象方式

export default {

    name: 'app',

    data: {

          level:''1"

    },

}

    如果data 是一个纯碎的对象,则所有的实例将共享引用同一份 data 数据对象,无论在哪个组件实例中修改 data,都会影响到所有的组件实例。如果 data 是函数,每次创建一个新实例后,调用 data 函数,从而返回初始数据的一个全新副本数据对象。这样每复用一次组件,会返回一份新的 data 数据,类似于给每个组件实例创建一个私有的空间,让各个组件的实例各自独立,互不影响保持低耦合 

11.不需要响应变化的数据可以放在实例里面,不要将所有的数据都放到 data 中

对应的lfl可以正常使用

created() {  

       this.lfl = '123'

  },

data 中的数据都会增加 getter 和 setter,又会收集 watcher,这样还占内存。不需要响应式的数据我们可以定义在实例上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值