前端优化——性能提升

 

优化清单:

1.路由模块按需加载

2.组件懒加载

3.Object.freeze() 冻结不再变更的对象

4.开启productionGzip 压缩

5.合理使用keep-alive保留组件状态,避免重新渲染

6.v-if与v-show根据具体业务场景适当选取

7.图片使用与加载优化

8.大数据列表使用vue-virtual-scroll-list优化

9.配置 externals 使库文件采用cdn加载

 

 

具体措施:

 

1.路由懒加载和组件懒加载

作用:

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了

 

操作:

使用ES 提出的import方法,(------最常用------

 

路由懒加载:

const HelloWorld = ()=>import('需要加载的模块地址')

指定chunkGroup的方式:

const Main = () => import(/* webpackChunkName: "chunk-main" */ '@/page/Main.vue')

 

import Vue from 'vue'

import Router from 'vue-router'

Vue.use(Router)

const HelloWorld = ()=>import("@/components/HelloWorld")

export default new Router({

  routes: [

    {

      path: '/',

      name: 'HelloWorld',

      component:HelloWorld

    }

  ]

})

组件懒加载:

<template>

  <div class="hello">

  <One-com></One-com>

  </div>

</template>

 

<script>

const One = ()=>import("./one");

export default {

  components:{

    "One-com":One

  },

  data () {

    return {

      msg: 'Welcome to Your Vue.js App'

    }

  }

}

</script>

 

 

2.Object.freeze() 冻结不再变更的对象

 

作用:

可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象

 

操作:

const obj = {

  prop: 42

};

Object.freeze(obj);

obj.prop = 33;

// Throws an error in strict mode

console.log(obj.prop);

// expected output: 42

 

 

3.使用keep-alive保留组件状态,避免重新渲染

作用:

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。

 

操作:

<!-- 基本 -->

<keep-alive>

<component :is="view"></component>

</keep-alive>

 

<!-- 多个条件判断的子组件 -->

<keep-alive>

<comp-a v-if="a > 1"></comp-a>

<comp-b v-else></comp-b>

</keep-alive>

 

<!-- 和 `<transition>` 一起使用 -->

<transition>

<keep-alive>

<component :is="view"></component>

</keep-alive>

</transition>

 

 

4.v-if与v-show根据具体业务场景适当选取

1、实现方式

  • v-if是根据后面数据的真假值判断直接从Dom树上删除或重建元素节点
  • v-show只是在修改元素的css样式,也就是display的属性值,元素始终在Dom树上。

2、编译过程

  • v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;
  • v-show只是简单的基于css切换;

3、编译条件

  • v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译;
  • v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素始终被保留;

4、性能消耗

  • v-if有更高的切换消耗,不适合做频繁的切换;
  • v-show有更高的初始渲染消耗,适合做频繁的额切换;

 

 

5.图片使用与加载优化

1.在支持webp 图片格式的浏览器上使用webp

2.使用 iconfont

3.SVG替换png,jpg

4.小图片直接使用base64(Webpack rule url-loader 已处理)

5.尽量主动设置img 标签的width ,height 属性

 

 

 

6.大数据列表使用vue-virtual-scroll-list优化

原理:

虚拟列表做的事情,就是按需渲染。只需要渲染当前视图需要显示的几个条目和即将滚动到的几个条目。在开发者工具中可以发现,DOM 中只存在这么几条列表项,当滚动的时候会替换这几项。所以大大节省了系统资源,提升了用户体验。

核心实现

this.$slots.default类型为数组,存储的是此组件两标签中的内容,在此特指大量的列表项。

通过 Vue 数组的 filter 方法,筛选出处于当前视图中的几个项,选择性的只渲染出这几个在 DOM 中。渲染是依据 Vue 的 render 函数来动态定义组件。

export default {

name: 'item',

props: [

'item',

'k'

],

render: function (createElement) {

return createElement(

'div',

this.$slots.default.filter(function (slot, index) {

return index > 5 && index < 10

})

)

}

}

 

操作

1.安装

npm install vue-virtual-scroll-list --save

2.使用

<template>

<div>

<virtual-list :size="40" :remain="8">

<item v-for="item of items" :key="item.id" />

</virtual-list>

</div>

</template>

<script>

import item from '../item.vue'

import virtualList from 'vue-virtual-scroll-list'

export default {

data () {

return {

items: [ {id: 1}, {id: 2}, {id: 3}, ... ]

}

},

components: { item, 'virtual-list': virtualList }

}

</script>

 

7.配置 externals 使库文件采用cdn加载

原理:

 

利用 webpack 的 externals 属性 。文档

官网的解释 :防止 将某些 import 的包(package) 打包 到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

通俗的解释:让某些资源包即使不在本地npm安装,通过 script 标签引入后也能使用

操作:
 

操作:

  • 首先在模板文件 index.html 中添加以下内容
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>XXXX平台</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.4.1/theme-chalk/index.css">
  </head>
  <body>
  <div id="app"></div>
  <script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
  <script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
  <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.17.0/axios.min.js"></script>
  <script src="https://cdn.bootcss.com/element-ui/2.4.1/index.js"></script>
    <!-- built files will be auto injected -->
  </body>
</html>
复制代码

注意!版本号要与 package.json 中的版本号一致

  • 修改 build/webpack.base.conf.js
module.exports = {
  ...
  externals: {
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'axios': 'axios',
    'element-ui': 'ELEMENT'
  }
  ...
}
复制代码

注意!这里 axios 变量名要使用 axios

注意!这里 element-ui 变量名要使用 ELEMENT,因为element-uiumd 模块名是 ELEMENT

  • 修改 src/router/index.js
// import Vue from 'vue'
import VueRouter from 'vue-router'
// 注释掉
// Vue.use(VueRouter)
...
}
复制代码
  • 修改 src/store/index.js
...
// 注释掉
// Vue.use(Vuex)
...
}
复制代码
  • 修改 src/main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'

// 注释掉
// import 'element-ui/lib/theme-chalk/index.css'  

// router setup
import router from './router'

// Vuex setup
import store from './store'
Vue.use(ElementUI)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

开了一个大前端技术交流群,也可直接加我微信入群(mokinzhao

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值