未加星标

详解使用vue-admin-template的优化历程

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 | 作者 红领巾 ] 0人收藏点击收藏

前言

公司有好几个项目都有后台管理系统,为了方便开发,所以选择了 vue 中比较火的后台模板 作为基础模板进行开发。但是,开始用的时候,作者并没有对此进行优化,到项目上线的时候,才发现,打包出来的文件都十分之大,就一个 vendor 就有 770k 的体积(下图是基础模板,什么都没加打包后的文件信息):

详解使用vue-admin-template的优化历程

通过 webpack-bundle-analyzer 进行分析可得,体积主要来源于饿了么UI(体积为 500k),因为没对其进行部分引入拆分组件,导致 webpack 把整个组件库都打包进去了。其次就是 vue 本身,体积也达到了 80k 之大。

详解使用vue-admin-template的优化历程

所以,对其进行打包优化,是一件刻不容缓的事情。

优化

优化主要目的有:

加快资源加载速度,减少用户等待的时间和首页白屏时间,提高用户体验。
加快打包速度,不要将时间浪费在等待打包上。

解决第一个问题,很多人都会想到资源文件放在 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>
<div id="app"></div>
<!-- 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-admin-template的优化历程

但是随之而来的就有问题了:

详解使用vue-admin-template的优化历程

明明我在本地开发,但是由于引入了线上的生产版本的 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 的体积。

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

axios: ajax 请求。
vuex: 全局状态管理。
js-cookie: 前端处理 cookie
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.json 和 static/js 下的 vendor.dll.js。

step 2 页面中引入 vendor

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

<div id="app"></div>
<!-- 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,这是很让人欣慰。

后记

使用了 cdn 和 dll 打包后,无论是打包速度还是页面加载的速度都有很大的提升。因此将此次优化记录下来,并传上了 GitHub 中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。


您可能感兴趣的文章:浅谈vue项目可以从哪些方面进行优化vue短信验证性能优化如何写入localstorage中Vue 项目代理设置的优化详解Vue打包优化之code splitingvue-cli项目优化方法- 缩短首屏加载时间vuejs项目打包之后的首屏加载优化及打包之后出现的问题Vue项目使用CDN优化首屏加载问题vue webpack打包优化操作技巧vue-cli webpack2项目打包优化分享vue项目中用cdn优化的方法

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

tags: js,vue,gt,lt,webpack,打包,vendor,dll,emitted,static,name,build,loader,kB,cdn
分页:12
转载请注明
本文标题:详解使用vue-admin-template的优化历程
本站链接:https://www.codesec.net/view/576831.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(156)