VUE 性能提升优化

VUE 性能提升优化

1.keep-alive

keep-alive是Vue的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁
用来缓存组件,避免多次加载相同的组件,减少性能消耗,提高用户体验

// 缓存全部
<div id="app">
  	<keep-alive>
	    <router-view></router-view>
    </keep-alive>
  </div>
// 1. 将缓存 name 为 home 的组件,如果有多个,可用逗号分
  	<keep-alive include='home'>
      <router-view/>
    </keep-alive>
// 2. 将不缓存 name 为 home 的组件,如果有多个,可用逗号分
	<keep-alive exclude='home'>
  	  <router-view/>
	</keep-alive>
// 3. 还可使用属性绑定动态判断
	<keep-alive :include='includedComs'>
  	  <router-view/>
	</keep-alive>

2.使用路由懒加载

Vue 是单页面应用,回应如多个路由,这样使用 webpcak 打包后的文件很大.,加入资源过多页面会卡 这个是需要用到路由懒加载

routes: [
		{
    
    
		  path: '/',
		  name: 'home',
		  component: ()=>import('@/home/index') }
		}
	]

3.图片懒加载 (vue-lazyload插件)

// npm install vue-lazyload --save-dev
// yarn add vue-lazyload --save-dev

//main.js
mport VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad, {
    
    
  preLoad: 1,
  error: require('./assets/img/error.jpg'),
  loading: require('./assets/img/loading.jpg'),
  attempt: 2,
})

//vue
//  img标签中使用vue-lazyload懒加载
//<img v-lazy="图片地址" :key="图片地址">
<img v-for="item in imglist" :key="item" v-lazy="item" alt=""> 

//  背景图中使用vue-lazyload懒加载
//<img v-lazy:background-image="图片地址" :key="图片地址">
<li v-for="item in imglist" :key="item"  v-lazy:background-image="item"></li>

4.Object.freeze 冻结对象

在 Vue 的文档中介绍数据绑定和响应时

特意标注了对于经过 Object.freeze() 方法的对象无法进行更新响应

把对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 劫持数据,添加 getter/setter,在属性被访问和修改时通知变化。
当我们用Object.freeze 对参数冻结时,不在被监听,从而到达优化。

当我们在页面遇到table表格 长列表 等等一些列的不需要监听的数据时就可以使用Object.freeze 冻结。

Object.freeze 有一下几个特性
1不能添加新属性
2不能删除已有属性
3不能修改已有属性的值
4不能修改原型
5不能修改已有属性的可枚举性、可配置性、可写性

// 
var obj = {
    
    
        name: '张三',
        age: 18,
    }
Object.freeze(obj)
obj.sea = "agy"
console.log(obj) // {name: "张三", age: 18} 不可新增
obj.name = "李四"
console.log(obj) // {name: "张三", age: 18} 不可修改
obj.__proto__ = "李四"
console.log(obj.__proto__) // 不可改变 {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} 
 
 // tips
// const 什么的常量也是不可修改不可新增 但是数组就行    
// Object.freeze 冻结的数组不能新增也不能修改 数组的本质也是对象
// 但是数组里面有对象的时候Object.freeze 就失效  Object.freeze()只支持浅冻结
 var obj = {
    
    
        name: '张三',
        group:{
    
    
            task:"1"
        }
    }
    Object.freeze(obj)
    obj.name="李四"
    console.log(obj) // 不可修改  {name: "张三", group: {tase:'1'}}
    obj.group.task="李四"
    console.log(obj)  // 可以修改 {name: "张三", group: {tase:'李四'}}

// 封装一个深冻结方法
const deepFreeze=(obj)=> {
    
    
    // 获取所有属性
    var propNames = Object.getOwnPropertyNames(obj)
    // 遍历
    propNames.forEach(item => {
    
    
        var prop = obj[item]
        // 如果某个属性的属性值是对象,则递归调用
        if (prop instanceof Object && prop !== null) {
    
    
            deepFreeze(prop)
        }
    })
    // 冻结自身
    return Object.freeze(obj)
}

5.事件的销毁

Vue 组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件

created() {
    
    
	tiem=setInterval(()=>{
    
    
        // ....
    })
  addEventListener('click', this.click, false)
},
beforeDestroy() {
    
    
  removeEventListener('click', this.click, false)
    clearInterval(time)
}

6.computed 和 watch 区分使用场景

computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
watch:更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

7.v-for 遍历必须为 item 添加 key,且避免同时使用 v-if

key的作用:提升v-for渲染的效率 提高渲染性能
key是虚拟dom对象的唯一标识。
v-for循环时,根据数据生成虚拟dom,在根据虚拟dom生成真实dom。

  • 当数据发生变化时,会生成新的虚拟dom
  • 然后vue会将新的虚拟dom和初始虚拟dom进行对比,即:diff算法
  • 如果新的虚拟dom中的key和初始虚拟dom中的key一致
  • 如果虚拟dom的内容没变,就直接复用之前的真实dom
  • 如果虚拟dom的内容变了,就生成新的dom节点,替换掉之前的
  • 如果新的虚拟dom中的key和初始虚拟dom中的key不一致
  • 就创建新的真实dom节点,随后渲染页面
// 不推荐
<div v-for="item in list" :key="item.id">
     <div v-if="item.isFlag"></div>
 </div>
// 推荐 用computed 替换掉v-if
<div v-for="item in list" :key="item.id">
 	<div>.....</div>
 </div>
computed: {
    
    
  list: function (item) {
    
    
    return item.filter((x)=>{
    
    return x.isFlag})
  }
}

7.插件按需加载

element 为列

// 首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件
npm install -D unplugin-vue-components unplugin-auto-import

// 方式一:写入 webpack.config.js
// Webpack安装
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const {
    
     ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = {
    
    
  // ...
  plugins: [
    AutoImport({
    
    
      resolvers: [ElementPlusResolver()],
    }),
    Components({
    
    
      resolvers: [ElementPlusResolver()],
    }),
  ],
}

// 方式二 写入 vue.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const {
    
     ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = {
    
    
  // vue.config.js 方式一 写法
  // configureWebpack: {
    
    
  //   plugins: [
  //     AutoImport({
    
    
  //       resolvers: [ElementPlusResolver()],
  //     }),
  //     Components({
    
    
  //       resolvers: [ElementPlusResolver()],
  //     }),
  //   ],
  // }
  
  // vue.config.js 方式二 写法
   chainWebpack: (config) => {
    
    
     config
       .plugin('AutoImport')
       .use(AutoImport({
    
     resolvers: [ElementPlusResolver()] }))
     config
       .plugin('Components')
       .use(Components({
    
     resolvers: [ElementPlusResolver()] }))
   }
}

8.babel es6转es5

安装babel-loader:

npm install --save dev babel-loader @7 babel-core babel-preset-es2015

//在 vue.config.js webpack 配置对象中,需要将 babel-loader 添加到 module 列表中
module: {
    
    
  rules: [
    {
    
    
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
    
    
        loader: 'babel-loader',
        options: {
    
    
          presets: ['es2015']
        }
      }
    }
  ]
}

9. cdn 打包优化

把一些版本改动小但包又很大的库放到index.html中,通过cdn引入

// 列如:
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.13/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
<src="https://cdn.bootcdn.net/ajax/libs/echarts/4.1.0/echarts.min.js"></script>

// 在vue.config.js   // 记得删除package.json中的依赖
module.exports = {
    
    
  configureWebpack:{
    
    
    externals:{
    
    
	  'vue': 'Vue',
	  'vue-router': 'VueRouter',
	  'vuex':'Vuex',
	  'echarts': 'echarts',
    },
  }
}

10.vue 打包 开启Gzpi

1.vue
安装插件(compression-webpack-plugin)

npm install compression-webpack-plugin --save-dev

配置vue.config.js文件

  const CompressionPlugin = require('compression-webpack-plugin');
  module.exports = {
    
    
    plugins: [
      new CompressionPlugin({
    
    
        algorithm: 'gzip', // 使用gzip压缩
        test: /\.js$|\.css$/, // 匹配文件名
        filename: '[path].gz[query]', // 压缩后的文件名(保持原文件名,后缀加.gz)
        minRatio: 1, // 压缩率小于1才会压缩
        threshold: 10240, // 对超过10k的数据压缩
        deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
      }),
    ],
  },
  };

2.nginx
conf-> nginx.conf

nginx
gzip使用环境:http,server,location,if(x),一般把它定义在nginx.conf的http{……}之间

http {
    
    
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip_static on;

    server {
    
    
        listen       8462;
        server_name  localhost;

        location / {
    
    
            root   dist;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
    
    
            root   html;
        }
    }

}

gzip on
on为启用,off为关闭
gzip_min_length 1k
设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。默认值是0,不管页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_buffers 4 16k
获取多少内存用于缓存压缩结果,‘4 16k’表示以16k*4为单位获得
gzip_comp_level 5
gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php
对特定的MIME类型生效,其中’text/html’被系统强制启用
gzip_http_version 1.1
识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码
gzip_vary on
启用应答头"Vary: Accept-Encoding"
gzip_proxied off
nginx做为反向代理时启用,off(关闭所有代理结果的数据的压缩),expired(启用压缩,如果header头中包括"Expires"头信息),no-cache(启用压缩,header头中包含"Cache-Control:no-cache"),no-store(启用压缩,header头中包含"Cache-Control:no-store"),private(启用压缩,header头中包含"Cache-Control:private"),no_last_modefied(启用压缩,header头中不包含"Last-Modified"),no_etag(启用压缩,如果header头中不包含"Etag"头信息),auth(启用压缩,如果header头中包含"Authorization"头信息)
gzip_disable msie6
(IE5.5和IE6 SP1使用msie6参数来禁止gzip压缩 )指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配),依赖于PCRE库
以上代码可以插入到 http {…}整个服务器的配置里,也可以插入到虚拟主机的 server {…}或者下面的location模块内

猜你喜欢

转载自blog.csdn.net/qq_44795810/article/details/125908423