一、何为Webpack
Webpack是 一个开源的JavaScript模块打包工具,其最核心的功能是解决模块之间的依赖,把各个模块按照特定的规则和顺序组织在一起,最终合并为一个JS文件或多个。
执行命令npm run serve 时,可以指定webpack的模式为production
"serve": "NODE_ENV=development vue-cli-service serve --mode production",
二、带宽的换算
目前我们的云服务器带宽为5M
三 、bundle 体积监控工具
1、VS Code中的插件Import Cost
可以帮助我们对引入模块的大小进行实时检测,或者只考虑引用其中的某些子模块
2、webpack-bundle-analyzer
它能够帮助我们分析一个bundle的构成
效果:
安装:
npm install --save-dev webpack-bundle-analyzer
实现代码:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'development') {
config.plugins.push(new BundleAnalyzerPlugin());
}
}
};
当你运行 vue-cli-service serve 时,Vue CLI 会将 process.env.NODE_ENV 设置为 “development”,当你运行 vue-cli-service build 时,Vue CLI 会将 process.env.NODE_ENV 设置为 “production”。在这两种情况下,process.env.NODE_ENV 的值都是由 Vue CLI 设置的。Vue CLI 会根据用户执行的命令来决定是设置为开发模式还是生产模式。
你也可以在脚本中设置:
"scripts": {
"build": "NODE_ENV=production vue-cli-service build"
}
四、优化
1、script 标签中添加属性defer=“defer”
如果 async=“async”:脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)
如果不使用 async 且 defer=“defer”:脚本将在页面完成解析时执行
如果既不使用 async 也不使用 defer:在浏览器继续解析页面之前,立即读取并执行脚本
2、查找阻塞页面下载的大文件,清除不必要的文件
因为项目是从其他框架引入进来的,所有引入了一些没有用的js。删除不必要代码大概在7M左右
3、压缩css、js
有些js ,修改源码后没有重新压缩,压缩后可减少1M左右的大小
4、使用CDN
如何使用阿里云CDN服务?
在vue.config.js 中配置就可以了
能从原来的32s提升为4s
5、页面渲染完成才加载其他的js和css文件
<script>
let url = [
'util/aes.js', 'cdn/html2canvas/html2canvas.min.js?v=1.0.0',
'cdn/echarts/4.6.0/echarts.min.js?v=1.0.0',
'cdn/xlsx/FileSaver.min.js',
'cdn/oss/aliyun-oss-sdk.min.js', 'cdn/Sortable.js',
'https://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js'
]
document.addEventListener('DOMContentLoaded', function () {
// 在这里编写在DOMContentLoaded事件触发时执行的代码
console.log('DOMContentLoaded event has occurred.');
let len = url.length;
for (let i = 0; i < len; i++) {
var scriptElement = document.createElement('script');
// 设置 script 元素的 src 属性,即脚本的 URL
if (url[i] != 'https://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js') {
scriptElement.src = '<%= BASE_URL %>' + url[i];
} else {
scriptElement.src = url[i];
}
// 添加 onload 和 onerror 事件处理程序
scriptElement.onload = function () {
console.log('Script loaded successfully.');
// 在这里可以执行一些与脚本加载成功相关的操作
};
scriptElement.onerror = function () {
console.error('Error loading script.');
// 在这里可以执行一些与脚本加载失败相关的操作
};
// 将 script 元素附加到文档的头部或其他位置
document.head.appendChild(scriptElement);
}
});
</script>
6、路由懒加载
当进入对应的路由时,采取加载对应的js、css文件
routers.push({
path: path,
// 此处处理的为第一层路由,component为/page/index,使用children的方式在router-view中展示最终路由对应内容
// component(resolve){
// require([`../page/index`],resolve)
// },
component: () => import('../page/index'),
children: [
{
path: path,
// component(resolve){
// require([`../${component}.vue`],resolve)
// //import(`../${component}.vue`)
// },
component: () => import(`../${component}.vue`),
name: name,
icon: icon,
meta: meta,
}
]
})
把require的地方替换成import,切记是箭头函数
切片后index.html 中会生成 进行预加载,但是这个项目我们有很对冗余的路由,因为前面是3个平台放在一个项目中的,目前只用了一个平台,所有没有必要把所有的css、js文件进行预加载,所以取消预加载
此次优化,项目从原来的40s控制在了3s以内,还有优化的空间,只是这个项目设计的内容比较多,先暂不深入优化
7、Gzip压缩
npm 淘宝镜像过期了,这样设置
npm config set "strict-ssl" false
安装compression-webpack-plugin
npm install compression-webpack-plugin
vue.config,js 添加
configureWebpack:(config)=>{
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
// 配置productionGzip-高级的方式
// 配置参数详解
// asset: 目标资源名称。 [file] 会被替换成原始资源。[path] 会被替换成原始资源的路径, [query] 会被替换成查询字符串。默认值是 "[path].gz[query]"。
// algorithm: 可以是 function(buf, callback) 或者字符串。对于字符串来说依照 zlib 的算法(或者 zopfli 的算法)。默认值是 "gzip"。
// test: 所有匹配该正则的资源都会被处理。默认值是全部资源。
// threshold: 只有大小大于该值的资源会被处理。单位是 bytes。默认值是 0。
// minRatio: 只有压缩率小于这个值的资源才会被处理。默认值是 0.8。
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path][base].gz', // '[path].gz[query]', 版本原因需换成[path][base].gz
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 1024,
minRatio: 0.8
})
)
}
},
nginx配置文件中添加
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
gzip_disable "MSIE [1-6]\.";
gzip_static on;
gzip_vary on;
效果:
传输文件大小由原来的5.3M变成了现在的1.6M
webpack优化系列七:首屏加载优化 可以查看一系列的webpack优化方案
chainWebpack之optimization.splitChunks的cacheGroups缓存组代码分块实践案
开发时的注意事项
- 路由、组件懒加载、按需加载Webpack会自动将应用划分为多个chunk,实现按需加载
- 引入项目框架时,先删除本次项目不用的资源,一定要及时删除没用的代码
- 静态文件一定要进行压缩,public文件中的js,css文件并没有通过webpack进行压缩,可以自行压缩或者修改构建流程
- 使用CDN进行加速,CDN的费用相对便宜,能加速不少。修改静态资源时,记得添加一个版本号?v=1.0.0。以免取得cdn缓存的值。记得设置CDN的缓存时间,好像CDN的默认缓存时间为1小时
- 使用Webpack的externals配置项:将一些不需要打包的模块通过CDN引入,减小打包体积
- 使用Webpack的Tree Shaking功能可以去除项目中未使用的代码,减小打包后的文件大小。可以通过配置optimization中的usedExports选项来实现。。webpack 默认为usedExports=true;
- 开启gzip压缩compression-webpack-plugin:在服务器端配置gzip压缩,可以减小传输过程中的数据量,提高加载速度,对打包文件进行压缩,减小文件大小,加快加载速度。webpack优化系列二:Vue配置compression-webpack-plugin实现Gzip压缩
- 预加载关键资源,使用或标签,在首次加载完成后,提前加载其他资源。
- 代码分割:使用Webpack的代码分割功能,将代码分割成多个小块,实现按需加载,提高页面加载速度,配置SplitChunksPlugin,提取公共库和重复模块为单独的chunk,避免重复加载。webpack优化系列四:vue打包后生成的chunk-vendors文件过大,利用SplitChunks插件,分离chunk
- 减少外部库的依赖:尽可能减少不必要的库和框架的使用,以减少总体积。
- 升级 webpack 版本: 首先,确保你正在使用最新版本的 webpack。新版本通常会改进性能,并修复一些已知的问题。可以通过升级 webpack 和其相关插件来获得更好的性能。
- 去掉代码中的console.logwebpack优化系列六:vue项目配置 terser-webpack-plugin 压缩 JS,去除console
- 将public的静态资源移入assets。静态资源应该放在assets下,public只会单纯的复制到dist,应该放置不经webpack处理的文件,比如不兼容webpack的库,需要指定文件名的文件等等