vue項目優化上線

1 項目優化策略

1.1 生成打包報告

打包時,爲了直觀地發現項目中存在的問題,能夠在打包時生成報告。生成報告的方式有兩種:javascript

  1. 經過命令行參數的形式生成報告
    經過 vue-cli 的命令選項能夠生成打包報告
    --report 選項能夠生成 report.html 以幫助分析包內容
    vue-cli-service build --report
  2. 經過可視化的UI面板直接查看報告(推薦)
    在可視化的UI面板中,經過控制檯和分析面板,能夠方便地看到項目中所存在的問題。

1.2 經過 vue.config.js 修改 webpack 的默認配置

經過 vue-cli 3.0 工具生成的項目,默認隱藏了全部 webpack 的配置項css

若是有修改 webpack 默認配置的需求,能夠在項目根目錄中,按需建立 vue.config.js 這個配置文件,從而對項目的打包發佈過程作自定義的配置
(具體配置參考:地址)。html

1.3 爲開發模式與發佈模式指定不一樣的打包入口

默認狀況下,Vue項目的開發模式與發佈模式,共用同一個打包的入口文件(即 src/main.js)。爲了將項目的開發過程與發佈過程分離,咱們能夠爲兩種模式,各自指定打包的入口文件,即:vue

  • 開發模式的入口文件爲 src/main-dev.js
  • 發佈模式的入口文件爲 src/main-prod.js

1.4 configureWebpack 和 chainWebpack

在 vue.config.js 導出的配置對象中,新增 configureWebpack 或 chainWebpack 節點,來自定義 webpack 的打包配置。java

在這裏, configureWebpack 和 chainWebpack 的做用相同,惟一的區別就是它們修改 webpack 配置的方式不一樣:webpack

  • chainWebpack 經過鏈式編程的形式,來修改默認的 webpack 配置
  • configureWebpack 經過操做對象的形式,來修改默認的 webpack 配置

二者具體的使用差別,可參考以下網址:地址ios

1.5 經過 chainWebpack 自定義打包入口

module.exports = {
 chainWebpack: config => {
 config.when(process.env.NODE_ENV === 'production', config => {
 // entry默認打包入口
 config.entry('app').clear().add('./src/main-prod.js')
 })
 config.when(process.env.NODE_ENV === 'development', config => {
 config.entry('app').clear().add('./src/main-dev.js')
 })
}
}

1.6 經過 externals 加載外部 CDN 資源

默認狀況下,經過 import 語法導入的第三方依賴包,最終會被打包合併到同一個文件中,從而致使打包成功後,單文件體積過大的問題。web

爲了解決上述問題,能夠經過 webpack 的 externals 節點,來配置並加載外部的 CDN 資源。凡是聲明在externals 中的第三方依賴包,都不會被打包。vue-router

// vue.config.js
config.set('externals', {
  vue: 'Vue',
  'vue-router': 'VueRouter',
  axios: 'axios'
})
// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.when(process.env.NODE_ENV === 'production', config => {
      // entry默認打包入口
      config.entry('app').clear().add('./src/main-prod.js')
      config.set('externals', {
        vue: 'Vue',
        'vue-router': 'VueRouter',
        axios: 'axios'
      })
    })
    config.when(process.env.NODE_ENV === 'development', config => {
      config.entry('app').clear().add('./src/main-dev.js')
    })
  }
}

須要在 public/index.html 文件的頭部,添加 CDN 資源引用:vue-cli

<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

1.7 經過 CDN 優化 ElementUI 的打包

雖然在開發階段,咱們啓用了 element-ui 組件的按需加載,儘量的減小了打包的體積,可是那些被按需加載的組件,仍是佔用了較大的文件體積。此時,咱們能夠將 element-ui 中的組件,也經過 CDN 的形式來加載,這樣可以進一步減少打包後的文件體積。

  • 在 main-prod.js 中,註釋掉 element-ui 按需加載的代碼
  • 在 index.html 的頭部區域中,經過 CDN 加載 element-ui 的 js 和 css 樣式
<!-- element-ui 的 css 文件 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/>

<!-- element-ui 的 js 文件 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

1.8 首頁內容定製

不一樣的打包環境下,首頁內容可能會有所不一樣。咱們能夠經過插件的方式進行定製,插件配置以下:

module.exports = {
  chainWebpack: config => {
    // 發佈模式
    config.when(process.env.NODE_ENV === 'production', config => {
      config.entry('app').clear().add('./src/main-prod.js')

      // 插件名稱 html tap修改插件的相關參數 args 是參數項
      config.plugin('html').tap(args => {
        // 添加isProd自定義屬性
        args[0].isProd = true
        return args
      })
    })
    // 開發模式
    config.when(process.env.NODE_ENV === 'development', config => {
      config.entry('app').clear().add('./src/main-dev.js')

      config.plugin('html').tap(args => {
        args[0].isProd = false
        return args
      })
    })
  }
}

在 public/index.html 首頁中,能夠根據 isProd 的值,來決定如何渲染頁面結構:

<!– 按需渲染頁面的標題 -->
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>電商後臺管理系統</title>
<!– 按需加載外部的 CDN 資源 -->
<% if(htmlWebpackPlugin.options.isProd) { %>
<!—經過 externals 加載的外部 CDN 資源-->
<% } %>
// public/index.html
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <title><%= htmlWebpackPlugin.options.isProd ? '':'dev -' %>Emrof記錄</title>

    <!-- 是否加載CDN資源 -->
    <% if(htmlWebpackPlugin.options.isProd){ %>
    <!-- element-ui 的 css 文件 -->
    <link
      rel="stylesheet"
      href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
    />

    <!-- 引入組件庫 -->
    <script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

    <script
      type="text/javascript"
      src="https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js"
    ></script>

    <!-- element-ui 的 js 文件 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <% } %>
  </head>
  <body>
    <noscript>
      <strong
        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
        properly without JavaScript enabled. Please enable it to
        continue.</strong
      >
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

1.9 路由懶加載

當打包構建項目時,JavaScript 包會變得很是大,影響頁面加載。若是咱們能把不一樣路由對應的組件分割成不一樣的代碼塊,而後當路由被訪問的時候才加載對應組件,這樣就更加高效了。
具體須要 3 步:

  1. 安裝 @babel/plugin-syntax-dynamic-import 包。
  2. 在 babel.config.js 配置文件中聲明該插件。
  3. 將路由改成按需加載的形式,示例代碼以下:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')

關於路由懶加載的詳細文檔,參考以下:地址

image.png

image.png

image.png

image.png

image.png

2 項目上線

2.1 開啓 gzip 配置

使用 gzip 能夠減少文件體積,使傳輸速度更快。

能夠經過服務器端使用 Express 作 gzip 壓縮。其配置以下:

// 安裝相應包
 npm install compression -S
 // 導入包
 const compression = require('compression');
 // 啓用中間件
 app.use(compression());
const express = require('express')

// const expressJwt = require('express-jwt')
const compression = require('compression');
// 建立服務器
const app = express()

// gzip 壓縮
app.use(compression());

app.listen(8889, () => {
    console.log('服務器啓動成功!');
})
相關文章
相關標籤/搜索