共计 4848 个字符,预计需要花费 13 分钟才能阅读完成。
1、背景
以后网站我的项目采纳的是多页面,开发和重构拆散,开发新页面时,因为重构开发可能常常会增加款式文件或者调整款式程序,因而小组采纳了如下开发模式
随着页面越来越多,依赖的款式文件变多,gulp
工作也随之变多,打包编译速度慢的问题逐步裸露进去,这种模式下的打包工夫截图如下:
能够看到 gulp
工作大概须要 30s
, webpack 工作须要30s
, 加起来第一次构建须要 1 分多钟,而二次构建也须要 8 秒左右,设想每次构建脑袋中都跳出这个场景,这能忍耐?可见曾经到了必(ren) 须(wu)要 (ke) 改(ren)的境地了好吗
于是决定批改以后构建形式,分为以下步骤进行
1、去掉 gulp
批改后的模式如下图,其中绿色为新增流程,和原流程相比去掉了 gulp
打包 css
流程转而也交给 webpack
解决
切换到这种模式后,第一次打包工夫大概 20s, 增量编译大略 8s
2、webpack
构建速度优化
2.1 exclude include
优化
在匹配规定里指定须要解决和排除在外不解决的文件,放大查找和解决文件范畴,确保编译尽可能少的文件,针对我的项目状况增加对应的 include
和exclude
配置,具体配置如下
rules: [
{test: /\.[jt]s$/,
include: [path.resolve(process.cwd(), 'src')],
exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')],
},
{
test: /\.css$/,
include: RESOURCES.CSS.cwd,
}
]
加上下面配置后,第一次打包工夫大概 16s, 增量编译大略 8s
2.2 thread-loader
和 esbuild-loader
优化
thread-loader
是采纳多过程打包的形式,放在 thread-loader
前面的 loader
会独自的 worker
池里运行,esbuild
是由 Go
开发的用于打包压缩 ts
、js
的工具,特点是打包速速很快,官网 github
介绍与 webpack
, rollup
, Parcel
相比拟要快几十甚至上百倍,然而 esbuild 目前还不能反对 css, 并且没有插件机制,所以目前临时代替不了 webpack,然而有用于 webpack
中的 loader
即esbuild-loader
, 引入一下试一下成果, Vite
和 Snowpack
底层都采纳了 esbuild
,参考thread-loader
官网阐明和 esbuild-loader
官网阐明后要害配置如下
const cpuNum = require('os').cpus().length;
const tsWorkerPool = {
workers: 6,
poolTimeout: Infinity
};
const cssWorkerPool = {
workers: cpuNum - tsWorkerPool.workers,
poolTimeout: Infinity
};
threadLoader.warmup(tsWorkerPool, ['esbuild-loader']);
threadLoader.warmup(cssWorkerPool, ['css-loader']);
module: {
rules: [
{test: /\.[jt]s$/,
use: [
{
loader: 'thread-loader',
options: tsWorkerPool
},
{
loader: 'esbuild-loader',
options: {
loader: 'ts',
target: 'es2015',
tsconfigRaw: require('../tsconfig.json')
},
},
{loader: path.resolve(__dirname, 'loaders/importcss-loader.js'),
options: {include: path.resolve(process.cwd(), 'src/app'),
}
},
],
include: [path.resolve(process.cwd(), 'src')],
exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')],
},
{
test: /\.css$/,
use: [
{loader: MiniCssExtractPlugin.loader,},
{
loader: 'thread-loader',
options: cssWorkerPool
},
{
loader: 'css-loader',
options: {esModule: false,}
},
{
loader: 'esbuild-loader',
options: {
loader: 'css',
minify: true
}
}
],
include: RESOURCES.CSS.cwd,
}
],
},
通过测试,加上 thread-loader
后,第一次打包工夫大概 12s
, 增量编译大略3s
, 再加上esbuild-loader
后,第一次打包工夫缩短到 8s
左右,增量编译大略 2s
留神: https://esbuild.github.io/api/#target
文档中提到针对大部分语法 esbuild-loader
只反对转换到es6
,因而只适宜在开发环境应用,生产环境不倡议应用
2.3 图片压缩和去掉冗余 css 款式文件
图片压缩配置如下
loader: 'image-webpack-loader',
options: {
// 生产环境启用压缩
disable: process.env.NODE_ENV === 'production' ? false : true,
// 压缩 jpg/jpeg 图片
mozjpeg: {
progressive: true,
quality: 80 // 压缩率
},
// 压缩 png 图片
pngquant: {quality: [0.65, 0.90],
speed: 4
}
}
去掉冗余款式应用 purgecss 插件,配置如下, 须要针对非凡的不能去除的加上配置
new PurgecssPlugin({
paths: glob.sync([path.resolve(__dirname, '../../server/views/**/*.html'),
path.resolve(`${PATH.SRC}/**/*.vue`),
]),
safelist: [
/data-v-.*/, // vue scope 款式保留
/market-message/, // 解决营销告诉栏背景色彩由配置决定导致须要剔除款式不确定的非凡解决
/vip/, // 动静渲染 vip 等级款式保留
]
})
3、降级到webpack5
webpack
去年公布了 webpack5
带来了很多优化,次要几点比方:
1、默认开启长久化缓存并缓存在内存中,而 webpack4
则须要借助 cache-loader
和hard-source-webpack-plugin
来做缓存
2、NodeJS
的polyfill
脚本被移除, 而在 webpack4
及以前的版本中,对于大多数的 Node
模块将主动增加 polyfill
脚本,导致打包后体积会变大。
3、更好的 TreeShaking
通过下面优化后,想进一步测试一下 webpack5
版本能带来的优化成果,将 webpack
包和相干依赖降级到最新版本,去掉不兼容的 speed-measure-webpack-plugin
和曾经不须要的 hard-source-webpack-plugin
插件后,解决大略 65 个文件,第一次打包工夫缩短到 6.5s
左右,增量编译工夫 1.5s
左右,能够看到工夫进一步缩短。
4、热加载和热更新
webpack.dev.js
中增加以下配置
devServer: {contentBase: path.join(PATH.DIST, 'js'),
inline: true,
compress: true,
port: 5000,
writeToDisk: true,
host: '0.0.0.0',
hot: true,
disableHostCheck: true,
headers: {
'Access-Control-Allow-Origin': 'https://www.midasbuy.com',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Credentials': true,
},
},
因为咱们开发时是用的 whistle
代理配合域名拜访, 在检测到文件文件更新时是通过 websocket
来进行音讯告诉的,因而须要在 whistle
中增加规定如下, 第一条是建设 websocket
连贯,第二条用于热更新时申请更新的内容, 这里次要实现了 vue
组件的热更新和 js
的热刷新,css 热跟新临时没实现。
https://www.midasbuy.com:5000 http://127.0.0.1:5000/
^https://www.midasbuy.com/oversea_web/static/***hot-update*** http://127.0.0.1:5000/oversea_web/static/$1hot-update$2
坑:测试热刷新时,批改了文件, 页面刷新后展现如下报错
而后再次手动刷新就好了,半天没找到起因,一度还狐疑是 whistle
代理的起因,之后狐疑是发送告诉更新指令太早了,而后写了一个 hack
办法来提早发送更新指令,发现能够了,然而具体起因还没找到,直到切换到服务端终端,更新文件时看到了如下打印
才明确了,咱们的流程是 client
端编译好文件后,会将文件复制到 server
文件夹上面来提供给 ejs include
进来应用,server
应用了 nodemon
,文件变更时会进行复制文件操作,触发了nodemon
的重启导致浏览器 reload
时申请失败,所以解决办法是在 nodemon
配置文件中把复制文件的目录疏忽掉,因为复制的真正内容是 <style link='*****'></style>
和<script src='*****'></script>
这样的内容,所以齐全是能够疏忽的,疏忽后文件变更时服务端也不会重启,问题解决。
5、vue devtools
定位到组件目录
针对 vue devtools
提供的在浏览器抉择组件时,点击时能够间接关上编译器并关上组件所在源代码文件,参考文档在 webpack.dev.js
下新增上面配置
const openInEditor = require('launch-editor-middleware');
devServer: {
...
before(app) {app.use('/__open-in-editor', openInEditor('code', path.resolve(process.cwd(), 'src')));
},
},
在 whistle
增加一行规定
https://www.midasbuy.com/__open-in-editor http://127.0.0.1:5000/__open-in-editor
如下图,点击圈出的该地位时会关上 vscode
编辑器并定位到组件对应源文件代码
6、总结
在 MacBook Pro Intel Core i7 16G
内存 250G
硬盘大小测试环境下 比照不同计划下的编译工夫和次要文件的 gzip
压缩前的大小后果如下,在解决大概 65
个文件状况下,能够看到编译工夫大大缩短,js
文件大小也有所减小,然而因为局部图片被 base64
编码打进 css
导致款式文件大小有所增加。
计划 | 第一次编译工夫 | 第二次编译工夫 | buypage.js |
propsOrder.js |
buypage.css |
propsOrder.css |
---|---|---|---|---|---|---|
gulp +webpack4 |
60s |
8s |
178kb |
157kb |
17.58kb |
24.74kb |
webpack5 |
6.5s |
1.5s |
123kb |
112kb |
28kb |
35kb |