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 |