本文章上接搭建篇,由于篇幅缘由,我把优化单独放一篇文章来说。css
代码我都上传到了github,有须要的自取。Webpack-Vue-Mobilevue
大佬绕路轻喷node
不少时候作开发都会使用UI组件库,这些组件库通常都会有按需加载的功能,这里我选择vant组件库来测试。手头暂时没有能够演示的项目,可能有点纯理论感受,可是应该能你们一个优化的思路。我会在测试项目里面写一些测试页面,到时上传到github供你们参考!webpack
注意: 通过我前面的一些实践,这儿有事情须要告知ios
安装vantgit
npm install vant
复制代码
安装完毕后,咱们先使用官网的全局导入全部组件github
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
复制代码
而后你到页面使用几个组件,好比Button,Dialog这些,运行npm run dev命令,这时发现报错了,说Module parse failed: Unexpected character '@',这是由于咱们引入vant时,引入了css文件,可是咱们的webpack并无配置处理css的loader,因此加上便可:web
{
test: /\.css$/,
// 这儿组件库的css通常都是处理过的,咱们使用通常的loader便可
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
}
]
}
复制代码
这样咱们就能运行并加入相关组件了,这里咱们不演示组件使用,而是直接打包展现结果分析图:正则表达式
咱们能够看见那个硕大的index.css,也就是说你没用到的组件它也把样式这些都弄进来了。
npm install babel-plugin-import -D
复制代码
安装完毕后在babel.config.js里面配置:
// 按需加载vant组件
plugins: [
["import", {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
复制代码
这样你在main.js里面这样引入便可:
// 按需注册vant组件
import { Button } from 'vant';
Vue.use(Button);
复制代码
你使用了什么组件就注册什么组件,目前社区上的许多ui组件库都是支持按需加载的,有的话必定要使用这种方式。
这下看下,比刚才所有引入好多了,额。。main.js硕大应该是未分离全部东西打包到一块儿的缘由-_-!。
使用路由懒加载,在页面访问到是再加载对应的资源,提高首页访问的速度。 在这以前,咱们还须要一个babel插件来实现这个功能
npm install @babel/plugin-syntax-dynamic-import -D
复制代码
安装完毕后,在webpack里面babel-loader配置加上如下代码:
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
// 使用vue官方的懒加载语法并结合babel需使用这个插件,否则会报错
plugins: ["@babel/plugin-syntax-dynamic-import"]
}
}
]
}
复制代码
而后咱们现有的路由里面引入组件的写法须要改变下,好比你如今是这么写的:
import Home from '../views/Home.vue';
import RouterTest from '../views/RouterTest.vue';
import VantTest from '../views/VantTest.vue';
复制代码
改为下面的写法:
//官方的懒加载方案,须要在webpack.config.js中配置@babel/plugin-syntax-dynamic-import这个插件,不然babel不支持如下语法会报错。
//下面的注释语法是打包生成的js的文件名,若是你想某几个组件打包到同一个文件,那么它们的注释语法的webpackChunkName的名字相同便可
const MainPage = () =>
import(/* webpackChunkName: "group-foo" */ "./views/MainPage.vue");
const ComOne = () =>
import(/* webpackChunkName: "group-foo" */ "./views/ComOne.vue");
const ComTwo = () =>
import(/* webpackChunkName: "group-foo" */ "./views/ComTwo.vue");
复制代码
这样处理后你会发现你在切换路由时会加载额外的js文件,这样咱们就分离了出来按需加载,打包分析图以下:
这里能够发现一个问题,咱们不少包都重复打了,接下来就是去除重复打包。因此咱们要提取公共代码。
在webpack3的时候,咱们能够借助CommonsChunkPlugin来实现,webpack4已经移除了这个插件,在webpack4中能够用splitChunks。
若是你在使用webpack4的时候没有作optimization.splitChunks的配置,那么它会有一个默认配置,官方文档的代码块:
module.exports = {
...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
...
}
复制代码
大多数状况咱们须要本身配置cashGroups这个参数,也就是自定义拆分组,这里我参考了社区大佬的配置,而后优化了下:
optimization: {
splitChunks: {
cacheGroups: {
// node_modules下的模块拆分到chunk-vendors.xxxx.js下
vendors: {
name: 'chunk-vendors',
test: /[\\\/]node_modules[\\\/]/,
priority: -10,
chunks: 'all'
},
// 本身定义的公告组件超过两次引用的放在chunk-common.xxxx.js下
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'all',
reuseExistingChunk: true
}
}
}
}
复制代码
一开始,chunks的属性值都是initial,而后咱们看一下打包分析图:
能够看到分离的js文件都打包了一次core.js文件,因此我把chunks参数值改成all,再来看分析图:
这样,就没有重复打包了。
在翻阅了社区上的一些文章后(官方文档对于我这个菜鸡来讲看不出来什么-_-),在此仍是作一个总结。
chunks 有all、async和initial三个值,async表示只从异步加载得模块(动态加载import())里面进行拆分 initial表示只从入口模块进行拆分 all表示以上二者都包括。
automaticNameDelimiter 打包拆分出来文件名的链接符,通常都是~。
maxAsyncRequests 按需加载时的最大并行请求数。
maxInitialRequests 入口并行加载的最大请求数。
minChunks 当应用次数超过多少次时会打包到单独的块,通常都是2。
minSize 生成块的最小大小(以字节为单位)。
maxSize 这个有点复杂,暂时说不清。#手动捂脸
name 分割的块名。
cashGroups 缓存组,这个能够本身来指定你的拆分规则,同时它的参数跟上面同样,声明了的话就是覆盖,不然就是继承,同时它还有几个独有的选项
关于这个参数的做用,我引用思否大佬的一个回答:
优化持久化缓存的, runtime 指的是 webpack 的运行环境(具体做用就是模块解析, 加载) 和 模块信息清单, 模块信息清单在每次有模块变动(hash 变动)时都会变动, 因此咱们想把这部分代码单独打包出来, 配合后端缓存策略, 这样就不会由于某个模块的变动致使包含模块信息的模块(一般会被包含在最后一个 bundle 中)缓存失效。optimization.runtimeChunk 就是告诉 webpack 是否要把这部分单独打包出来。连接
就是说呢那些不会常常变的runtime把它单独提出来,不须要频繁的产生变化,用来优化后端的缓存策略。
那么在webpack的配置文件加上这句:
optimization: {
runtimeChunk: true,
splitChunks: {
......
}
}
复制代码
设置好后,咱们打包出来试一试看相比于上面的配置会有哪些区别:
这下你发现main.js进一步减少了,把里面的部份内容放到了runtime~main下面。
若是还想进一步减少包的体积,除了你的图片媒体资源这些使用oss外。你的第三方库也可使用cdn分发网络,好比个人公司项目的axios,vue,better-scroll这些都使用了cdn分发的方式,而不是直接导入到包里面一块儿打包。 在你的index.html入口页面下以这种方式加入
<script src="https://static.XXXXXX.com/12static/new/js/vue.min.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/vue-router.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/axios.min.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/bscroll.min.js"></script>
复制代码
这里给你们推荐一个开源的第三方cdn分发网络:BootCDN
暂时到这里总结就结束了,可是优化的脚步不会停,我这儿的优化都是比较基本的优化,确定还有许多点没有总结到,后期如有使用到的好的优化方法,会持续更新,若文章有错误,还请多多指正!