文章目录
- 1. 按需加载
- 1.1 路由组件按需加载
- 1.2 第三方组件和插件按需加载
- 1.3 一些插件, 只在个别组件中用的上, 不需要在main.js中导入, 只需要在使用的页面导入即可
- 2 优化loader配置
- 3 优化文件路径-省下搜索文件的事件
- 4 生产环境关闭sourceMap
- 5 代码压缩
- 6 提取公共代码
- 7 CDN优化
- 8 使用HappyPack多进程解析和处理文件
提示:以下是本篇文章正文内容,下面案例可供参考
1. 按需加载
1.1 路由组件按需加载
const router = [
{
path: '/index',
component: resolve => require.ensure([], () => resolve(require('@/components/index')))
},
{
path: '/about',
component: resolve => require.ensure([], () => resolve(require('@/components/about')))
}
]
1.2 第三方组件和插件按需加载
// 引入全部组件
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
// 按需引入组件
import { Button } from 'element-ui'
Vue.component(Button.name, Button)
1.3 一些插件, 只在个别组件中用的上, 不需要在main.js中导入, 只需要在使用的页面导入即可
// 在main.js引入
import Vue from vue
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
// 按组件按需引入
import { Vuelidate } from 'vuelidate'
2 优化loader配置
- 优化正则匹配
- 通过cacheDirectory选项来开启缓存
- 通过include、exclude来减少处理的文件
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [resolve('src')]
}
]
}
3 优化文件路径-省下搜索文件的事件
- extension 配置之后可以不用在 require 或是 import 的时候加文件扩展名,会依次尝试添加扩展名进行匹配。
- mainFiles 配置后不用加入文件名,会依次尝试添加的文件名进行匹配
- alias 通过配置别名可以加快 webpack 查找模块的速度。
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
}
4 生产环境关闭sourceMap
- sourceMap本质上是一种映射关系, 打包出来的js文件中的代码可以映射到代码文件的具体位置, 这种映射关系会帮助我们直接找到源码中的错误。
- 打包速度减慢, 生产文件变大, 所以开发环境用sourceMap, 生产环境关掉
5 代码压缩
- UglifyJS: vue-cli默认使用的压缩代码方式, 它使用的是单线程压缩代码, 打包事件较慢
- ParallelUglifyPlugin: 开启多个子进程, 把对多个文件压缩的工作分别给多个子进程去完成
plugins: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: true,
parallel: true
}),
new ParallelUglifyPlugin({
//缓存压缩后的结果,下次遇到一样的输入时直接从缓存中获取压缩后的结果并返回,
//cacheDir 用于配置缓存存放的目录路径。
cacheDir: '.cache/',
sourceMap: true,
uglifyJS: {
output: {
comments: false
},
compress: {
warnings: false
}
}
})
]
6 提取公共代码
- 相同资源重复被加载, 浪费用户流量, 增加服务器成本
- 每个页面需要加载的资源太大, 导致网页首屏加载缓慢, 影响用户体验
// webpack3 使用 CommonsChunkPlugin 的实现:
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module, count) {
console.log(module.resource, `引用次数${count}`)
//"有正在处理文件" + "这个文件是 .js 后缀" + "这个文件是在 node_modules 中"
return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, './node_modules')) === 0
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
chunks: 'initial',
minChunks: 2
})
]
// webpack4 使用 splitChunks 的实现:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
priority: 1, //添加权重
test: /node_modules/, //把这个目录下符合下面几个条件的库抽离出来
chunks: 'initial', //刚开始就要抽离
minChunks: 2 //重复2次使用的时候需要抽离出来
},
common: {
//公共的模块
chunks: 'initial',
minChunks: 2
}
}
}
}
}
7 CDN优化
- 随着项目越来越大, 依赖的第三方npm包越来越多, 构建之后的文件越来越大
- 再加上又是单页面应用, 首页加载会造成长时间的白屏
- 将vue/element-ui/axios/vue-router/vuex用在index.html中采用cdn方式引入
<head>
<link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css" rel="external nofollow" />
</head>
<body>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.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.2/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
<!-- built files will be auto injected -->
</body>
- 在webpack.config.js配置文件
module.exports = {
···
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
'Axios':'axios'
}
}
- 卸载依赖的npm包, npm uninstall vue vue-router vuex element-ui axios
- 修改mian.js中引入包的方式
// import Vue from 'vue'
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
// import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
import utils from './utils/Utils'
Vue.use(ELEMENT)
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'hash', //路由的模式
routes
})
new Vue({
router,
el: '#app',
render: h => h(App)
})
8 使用HappyPack多进程解析和处理文件
- 由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的事情需要一件一件的做,不能多件事一起做。
- HappyPack 就能让 Webpack 把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
- HappyPack 对 file-loader、url-loader 支持的不友好,所以不建议对该 loader 使用。
使用方法:
// 1. HappyPack插件安装: npm i -D happypack
// 2. webpack.base.conf.js文件对module.rules进行配置
module: {
rules: [
{
test: /\.js$/,
use: ['happypack/loader?id=babel'],
include: [resolve('src'), resolve('test')],
exclude: path.resolve(__dirname, 'node_modules')
},
{
test: /\.vue$/,
use: ['happypack/loader?id=vue']
}
]
}
// 3. 在生产环境 webpack.prod.conf.js 文件进行配置
const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
new HappyPack({
// 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
id: 'babel',
// 如何处理.js文件,用法和Loader配置中一样
loaders: ['babel-loader?cacheDirectory'],
threadPool: HappyPackThreadPool
}),
new HappyPack({
id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
loaders: [
{
loader: 'vue-loader',
options: vueLoaderConfig
}
],
threadPool: HappyPackThreadPool
})
]
下次再见