首頁  >  文章  >  web前端  >  使用vue-admin-template優化步驟詳解

使用vue-admin-template優化步驟詳解

php中世界最好的语言
php中世界最好的语言原創
2018-05-28 15:06:023994瀏覽

這次帶給大家使用vue-admin-template優化步驟詳解,使用vue-admin-template優化的注意事項有哪些,下面就是實戰案例,一起來看一下。

前言

公司有好幾個專案都有後台管理系統,為了方便開發,所以選擇了vue 中比較火的後台模板作為基礎模板進行開發。但是,開始用的時候,作者並沒有對此進行優化,到專案上線的時候,才發現,打包出來的文件都十分之大,就一個vendor 就有770k 的體積(下圖是基礎模板,什麼都沒加打包後的檔案資訊):

透過webpack-bundle-analyzer 進行分析可得,體積主要來自餓了麼UI(體積為500k),因為沒對其進行部分引入分割元件,導致webpack 把整個元件庫都打包進去了。其次是 vue 本身,體積也達到了 80k 之大。

所以,對其進行打包優化,是一件刻不容緩的事情。

優化

最佳化主要目的有:

  1. 加快資源載入速度,減少使用者等待的時間和首頁白螢幕時間,提高使用者體驗。

  2. 加快打包速度,不要將時間浪費在等待打包上。

解決第一個問題,很多人都會想到資源檔案放在 CDN 上就好了,沒錯,這次我們就是透過 CDN 來解決載入問題。

CDN - 提高載入速度

像vue, element ui 這些比較成熟的框架/元件庫,一般都有免費、高速、公共的cdn 供開發者使用,鑑於大部分使用者都在國內,所以這次使用了bootcdn 這個函式庫。該庫熱門資源比較齊全,各個版本都有,而且國內訪問速度很快,簡直是開發者的福音。

index.html 中引入 vue 和 餓了麼元件。

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>vue-admin-template</title>
  <!-- 同时也要引入对应版本的 css -->
  <link href="https://cdn.bootcss.com/element-ui/2.3.2/theme-chalk/index.css" rel="external nofollow" rel="stylesheet">
 </head>
 <body>
  <p id="app"></p>
  <!-- built files will be auto injected -->
  <!-- 先引入 Vue -->
  <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
  <!-- 引入组件库 -->
  <script src="https://cdn.bootcss.com/element-ui/2.3.2/index.js"></script>
  <script src="https://cdn.bootcss.com/element-ui/2.3.2/locale/zh-CN.min.js"></script>
 </body>
</html>

因為依賴是從外部引入的,所以需要告知 webpack 在打包時,依賴的來源。

修改webpack.base.conf.js

module.exports = {
 ...
 externals: {
  vue: 'Vue',
  'element-ui':'ELEMENT'
 }
}

再一次打包,確實能極大的壓縮了打包的體積,從700k 驟減至130k:

但是隨之而來的就有問題了:

#明明我在本地開發,但由於引入了線上的生產版本的vue 文件,因此vue-dev-tools 就無法進行偵錯。

因此,我們需要再調整一下webpack 的配置,webpack.base.conf.js,而且webpack 注入的js 總是在最後的,因此,我們需要 html-webpack-include-assets-plugin 幫忙在註入app.js 後,再注入相對應的元件庫:

const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin')
const externals = {
 // 因为打包时,还没注入,所以这里要去掉。
 // 'element-ui':'ELEMENT'
}
// 生产环境中使用生产环境的 vue
// 开发环境继续使用本地 node_modules 中的 vue
if (process.env.NODE_ENV === 'production') {
 externals['vue'] = 'Vue'
 // 如发现打包时依旧将 element-ui 打包进入 vendor,可以在打包时将其加入外部依赖。
 externals['element-ui'] = 'ELEMENT'
}
// 生产环境默认注入 vue 
// 开发环境中不注入
const defaultJS = process.env.NODE_ENV === 'production' ? [{ path: 'https://cdn.bootcss.com/vue/2.4.2/vue.min.js', type: 'js' }] : []
const plugins = [
 new HtmlWebpackIncludeAssetsPlugin({
   assets: defaultJS.concat([
    { path: 'https://cdn.bootcss.com/element-ui/2.3.2/index.js', type: 'js' },
    { path: 'https://cdn.bootcss.com/element-ui/2.3.2/locale/zh-CN.min.js', type: 'js' },
   ]),
   // 是否在 webpack 注入的 js 文件后新增?true 为 append, false 为 prepend。
   // 生产环境中,这些 js 应该先加载。
   append: process.env.NODE_ENV !== 'production',
   publicPath: '',
  })
]
module.exports = {
 ...
 externals,
 plugins,
 ...
}

OK,這時候,既能兼顧打包後的體積大小,也能在開發模式中使用vue-dev-tool 進行調試。

DLL - 提高打包速度

經常打包的前端會發現,很多時候,我們為了修復某些bug(如promise 在ie Safari 下的bug),而新引進了一個polyfill,然而,打包完後發現,vendor 的hash 值變了,而整個vendor 只新加了一個es6-promise 的依賴,但是付出的代價就是,需要拋棄先前打包好的vendor,用戶重新造訪時,需要再一次拉取一個全新的vendor,這個代價就有點大了。

這時候,使用 dllPlugin 打包就有優勢了。它可以將一些基礎依賴模組統一先打包起來,當正式打包時,則可以略過這些模組,不再重複打包進去 vendor,提高打包速度的同時也能減少 vendor 的體積。

如,后台管理系统基础模块基本有以下几个:

  1. axios: ajax 请求。

  2. vuex: 全局状态管理。

  3. js-cookie: 前端处理 cookie

  4. vue-router: 路由管理。

这四个基础模块几乎是必须的,那么可以先提取出来。

step 1 打包基础模块

先在 build 文件夹下新建一个用于打包 dll 的配置文件 webpack.dll.conf.js

const webpack = require('webpack');
const path = require('path');
const vueLoaderConfig = require('./vue-loader.conf')
const utils = require('./utils')
function resolve(dir) {
  return path.join(dirname, '..', dir)
}
const vendor = [
  // 'vue/dist/vue.runtime.esm.js', // 由于 vue 在生产环境中使用的是 cdn 引入,所以也无需提前打包进 dll
  // 'raven-js', // 前端监控,若无此需求,可以忽略。
  'es6-promise', // 修复 promise 中某些 bug。
  'vue-router',
  'js-cookie',
  'axios',
  'vuex',
];
const webpackConfig = {
  context: dirname,
  output: {
    path: path.join(dirname, '../static/js/'),
    filename: '[name].dll.js',
    library: '[name]_[hash]',
  },
  entry: {
    vendor
  },
  plugins: [
    new webpack.DllPlugin({
      context: dirname,
      path: path.join(dirname, '.', '[name]-manifest.json'),
      name: '[name]_[hash]',
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
       warnings: false
      },
      sourceMap: true,
      // parallel: true
    })
  ],
  module: {
    rules: [{
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
};
module.exports = webpackConfig

然后在 package.json 中加入一条命令:

{
  "scripts": {
    ...
    "build:dll": "webpack --config build/webpack.dll.conf.js",
    ...
  }
}

执行 yarn build:dll 或者 npm run build:dll 即可完成打包 dll。执行完成后:

yarn build:dll
yarn run v1.5.1
$ webpack --config build/webpack.dll.conf.js
Hash: f6894dff019b2e0734af
Version: webpack 3.10.0
Time: 1295ms
     Asset   Size Chunks       Chunk Names
vendor.dll.js 62.6 kB    0 [emitted] vendor
  [8] dll vendor 12 bytes {0} [built]
  + 32 hidden modules
✨ Done in 1.89s.

同时,可以在 build 目录下,找到各个模块对应关系文件 vendors-manifest.jsonstatic/js 下的 vendor.dll.js

step 2 页面中引入 vendor

打包后的 dll 文件需要手动在 index.html 引入:

<p id="app"></p>
<!-- built files will be auto injected -->
<script src="static/js/vendors.dll.js"></script>

step 3 告诉 webpack 使用 dllPlugin 进行打包

修改 build/webpack.prod.conf.js:

module.exports = {
  plugins: [
    ...
    new webpack.DllReferencePlugin({
      context: dirname,
      manifest: require('./vendor-manifest.json')
    }),
    ...
  ]
}

再次打包:

$ yarn build:report
yarn run v1.5.1
$ npm_config_report=true node build/build.js
Hash: b4ff51852866ed865cfd
Version: webpack 3.10.0
Time: 6532ms
                       Asset    Size Chunks       Chunk Names
     static/js/manifest.42b9584a653aec2b9c5e.js   1.5 kB    5 [emitted] manifest
             static/img/404.a57b6f3.png  98.1 kB     [emitted]
        static/js/1.9e4133a25808e2101dd3.js    1 kB    1 [emitted]
        static/js/2.2a8a8e01c51473fab882.js  4.34 kB    2 [emitted]
      static/js/vendor.c7b076ef3341d4711402.js  39.4 kB    3 [emitted] vendor
       static/js/app.6d52c7a5bf1bacb5cc85.js  21.4 kB    4 [emitted] app
        static/js/0.cbc645864aab28ae8055.js  15.3 kB    0 [emitted]
static/css/app.1b30f8eba210e245a5f96d7bf0d6fb6c.css   7.6 kB    4 [emitted] app
                    favicon.ico  67.6 kB     [emitted]
                     index.html 986 bytes     [emitted]
              static/js/vendor.dll.js  62.6 kB     [emitted]
 Build complete.
 Tip: built files are meant to be served over an HTTP server.
 Opening index.html over file:// won't work.

发现 vendor 现在只有 40k 的体积,减少了一半的体积,而且打包速度也快了 2s,而相对于最开始的基础模板,打包速度快了 12s,这是很让人欣慰。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

如何使用v-model与promise两种方式实现vue弹窗组件

怎样使用Vue+Jwt+SpringBoot+Ldap完成登录认证

以上是使用vue-admin-template優化步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn