vue性能優化

1、webpack層面優化

CDN加載方式替換import方式

原理:

瀏覽器從服務器上下載 CSS、js 和圖片等文件時都要和服務器鏈接,而大部分服務器的帶寬有限,若是超過限制,網頁就半天反應不過來。而 CDN 能夠經過不一樣的域名來加載文件,從而使下載文件的併發鏈接數大大增長,且CDN 具備更好的可用性,更低的網絡延遲和丟包率 。css

操做:

// 文件:./src/index.html
<script src="https://cdn.bootcss.com/vue/2.5.3/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.0/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/clipboard.js/2.0.4/clipboard.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>

圖片base64轉碼

目的:圖片轉base64後,圖片打包進dist/app.js中,隨js一塊兒加載,減小http請求次數。圖片轉成base64後,文件體積變大了大約1/3左右

注意:

  • 文件的base64編碼存儲到了js文件中
  • vue-webpack模板的默認設置限制了轉碼的文件大小爲10000B如下
  • 靜態文件目錄中的全部文件不會被轉碼,也就是/static下的全部文件都不會被轉碼
  • 若是全部圖片均轉碼爲base64,那麼很容易形成存儲base64的js文件過大,一方面會形成資源加載時間過長的白屏問題,另外一方面也會給js解釋器帶來很是大的負擔,這樣反而起不到優化的做用,並且會很是影響體驗
  • 若是你非要讓全部圖片轉爲base64,能夠修改webpack中的url-loader配置

js/css文件壓縮

1.js文件切割

 

2.js文件壓縮

 

3.css文件切割加載

 

4.css文件壓縮

 

圖片壓縮


公共部分抽離

1.公共js文件抽離

 

2.公共css文件抽離

文件:./src/app.vue
<style lang="less">
    @import '~@/assets/styles/common.less';
</style>

3.less公共變量全局設置

方案一:全局配置

文件: build/utils.js

// cssLoaders中新增lessResourceLoader函數
// 修改return中less: generateLoaders('less')改成less: lessResourceLoader()
// 將全局less文件引入resources參數中
exports.cssLoaders = function (options) {
    
  function lessResourceLoader(){
    var loaders = [
        cssLoader,
        'less-loader',
        {
            loader: 'sass-resources-loader',
            options: {
                resources: [
                    // 引入全局less文件
                    path.resolve(__dirname, '../src/assets/styles/variables.less')
                ]
            }
        }
    ];
    if (options.extract) {
        return ExtractTextPlugin.extract({
            use: loaders,
            fallback: 'vue-style-loader'
        })
    } else {
        return ['vue-style-loader'].concat(loaders)
    }
  }
  
  return {
    // less: generateLoaders('less'),
    less: lessResourceLoader()
  }
}

方案二:在每一個vue文件style標籤中import引入

import '~@/assets/styles/variables.less'

externals配置不被打包的js文件

文件: ./build/webpack.base.config.js

externals:{
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex':'Vuex',
    'clipboard':'Clipboard',
    'axios':'axios',
    'vueLazyload':'LazyContainer'
},
鍵值對中的值爲三方件源碼中拋出的全局變量

設置是否生成source文件

文件:./build/webpack.prod.config.js

2、業務代碼層面優化

事件銷燬

created() {
   addEventListener('click', this.click, false)
 },
 beforeDestroy() {
   removeEventListener('click', this.click, false)
 }

圖片懶加載

原理:圖片過多,優先加載可視區域內的圖片html

方案一:插件

// 安裝vue-lazyload插件
npm install vue-lazyload --save-dev

// main.js中引入並全局註冊
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
    preLoad: 1.3,
    loading: require('@/assets/p/90_90.png'),
    attempt: 3,
    try: 2  //加載圖片數量
})

preLoad:1.3, //類型Number,默認1.3.表示lazyload的元素距離頁面底部距離的百分比.計算值爲(preload - 1).
attempt:3, //圖片加載失敗後的重試次數.默認爲3.
error:'', //類型string.圖片加載失敗後的顯示的失敗圖片路徑.
loading:'', //類型string.圖片正在加載中顯示的loading圖片的路徑.
listenEvents:[], //類型array.默認['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'].便是在監聽上述事件中,判斷圖片是否在preload的位置.若是你不想在那麼多事件中判斷,能夠指定一個或者幾個.例如若是你給這個屬性只指定['touchmove'].那麼scroll 屏幕不會加載圖片,只有手指滑動屏幕纔會加載圖片.
adapter:'', //註冊img的loading,loaded,error三個狀態的回調函數,參數會暴露懶加載的img元素,能夠對其進行操做.
filter:'', // img未加載以前,解析到src 的時候註冊的回調函數.能夠在加載圖片以前,對src進行修改.註冊在filter下的全部的函數都會執行
lazyComponent:false,//類型Boolean.是否啓用懶加載組件.組件中的內容只有在出如今preload的位置中才會加載組件.這個lazyloadComponent 組件有個缺點就是,組件在加載前是什麼都不渲染的,這樣子的話,有可能會影響佈局,以及加載前到加載後的切換很差,有點突兀和生硬.挖坑(vue懶加載組件)
observer:false, //是否啓用IntersectionObserver,這個api有兼容問題
observerOptions:{} //默認{ rootMargin: '0px', threshold: 0.1 }主要是我對這個pai不熟,按照vue-lazyload的說法是開啓以後,對不少節點的狀況會優化性能.挖坑吧
    
    
// 在img標籤中用v-lazy代替src
<img v-lazy="hotPurchaseImgList[index].imgUrl">

本地模擬

// 數據返回前渲染空頁面
// 數據返回後,渲染正常頁面
<listX  @isShowListX="getIsShowListX" v-if="isShowListX"/>
<listXP v-else="isShowListXP"/>

路由懶加載

const classify =
  {
    path: '/classify',
    name: 'classify',
    meta: { title: '分類' },
    redirect: '/classify/index',
    component: () => import('@/components/router'),
    children: [{
      path: 'index',
      name: 'classifyIndex',
      meta: { title: '分類' },
      component: () => import('@/view/classify/index')
    }, {
      path: 'list',
      name: 'classifyList',
      meta: { title: '分類' },
      component: () => import('@/view/classify/classListForItem')
    }]
  }
export default classify

三方件按需加載

方案一:babel-plugin-import按需引入 (以mand-mobile爲例)

// 安裝babel-plugin-import插件
 npm install babel-plugin-import -D
 
 // 修改.babelrc文件
 {
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

方案二:babel-plugin-component按需引入 (以element-ui爲例)

// 安裝babel-plugin-component插件
 npm install babel-plugin-component -D
 
 // 修改.babelrc文件
 {
   "plugins": [
     ["component", {
       "libraryName": "element-ui",
       "libraryDirectory": "lib",
       "styleLibraryName": "theme-chalk"
     }]
   ]
 }
 
 // main.js中按需引入
 import Vue from 'vue';
 import { Button, Select } from 'element-ui';

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

顯示類數據凍結雙向綁定,減小組件初始化時間

原理: Vue雙向綁定採用Object.defineProperty進行數據劫持實現,針對顯示類數據,無需進行數據劫持,採用Object.freeze凍結對象vue

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

3、服務器端渲染 & 預渲染

相關文章
相關標籤/搜索