之前,通过gzip的方式将访问速度从40多秒减少到7秒左右,但是仍然很慢。传送门
因为使用的服务器的带宽只有1M,所以即使gzip压缩后只有700K左右,但是仍然需要5秒左右的传输时间。
解决方法:1.缩小打包后的体积(减少至300K左右)2.将打包后的文件夹上传至腾讯云COS
项目说明
- 项目是使用
Create-React-app
创建的,没有进行eject
操作,所以需要使用react-app-rewired
与customize-cra
覆盖默认的配置。 - 项目使用的是
antd@3.x
版本,对于antd icon没有实现按需加载,虽然在antd@4.x
中修复了这个问题,但是迁移组件库的成本过大,所以只能使用antd@3.x
- 项目已经开启了gzip压缩,具体操作可以见之前一篇博客。
- 建议安装
webpack-bundle-analyzer
来帮助分析打包后的文件各模块大小
安装方法 npm install webpack-bundle-analyzer -D
修改config-ouverrides.js
const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
module.exports = override(
// antd按需加载
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: 'css',
}),
addWebpackPlugin(
new BundleAnalyzerPlugin({
analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
})
)
);
具体步骤
1.缩小打包后的体积(CDN加载)
项目有数据可视化的需求,所以使用了@antv/g2
作为可视化引擎。(echarts同理)
可以看见打包后的文件中,@antv/g2
和@antv/data-set
占据了较大的体积。
解决方法,将@antv/g2
和@antv/data-set
不做打包处理,而是采用CDN加载。
- 修改
index.html
,通过script标签加载@antv/g2
和@antv/data-set
<script src="https://gw.alipayobjects.com/os/lib/antv/g2/4.0.10/dist/g2.min.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.data-set-0.11.1/dist/data-set.js"></script>
- 使用
addWebpackExternals
方法修改external
const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
module.exports = override(
// 按需加载
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: 'css',
}),
addWebpackPlugin(
new BundleAnalyzerPlugin({
analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
})
),
addWebpackExternals(
{
// 不做打包处理配置,如直接以cdn引入的
'@antv/g2': 'window.G2',
"@antv/data-set": "window.DataSet",
// 'echarts': 'window.echarts' 如果使用的是echarts的话。
}
),
);
此时再执行build,原来654KB的js文件(gizp压缩后)现在只有363 KB(gizp压缩后)
现在gzip压缩后最大的js文件有363KB,但是由于服务器带宽只有1M,首屏加载时间依然需要4秒左右。
之后,笔者尝试过将antd组件库也改为CDN加载,打包后只有60KB左右,但是出现了一些问题,未能实现。看到一篇博文(https://www.cnblogs.com/cxscode/p/8075125.html),可能是解决的办法,但是由于项目过大,全部修改工作量太大,所以没有尝试这篇博文中提到的方法。如果有感兴趣的小伙伴可以尝试一下,欢迎评论区交流。
我们可以看到,现在的chunk.js文件中,体积最大的部分是antd的图标库。因为采用的是3.x版本,没有实现图标按需引入,而且好像就算你项目中没有直接使用icon,只要你使用了例如select等内置了图标的组件也会引入全部图标库,而升级到4.x的成本太大,基本上缩小打包文件体积进入了优化的深水区。
2.将打包后的文件上传至cdn
既然主要矛盾是服务器带宽小,文件传输慢,那就采用CDN加速。
笔者使用的是腾讯云COS,这边以COS为例。
前提工作
首先,你需要开通对象存储,创建存储桶,存储桶名称为bucket-xxxxxxxxx格式,前面是自定义名称,后面为appid
然后,开通默认cdn加速域名服务
这边获取到了源站域名和加速域名,接下来设置publicPath的时候使用源站域名。
设置publicPath
const { override, fixBabelImports, addWebpackExternals, addWebpackPlugin } = require('customize-cra');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
module.exports = override(
// 按需加载
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: 'css',
}),
addWebpackPlugin(
new BundleAnalyzerPlugin({
analyzerMode: 'static', //输出静态报告文件report.html,而不是启动一个web服务
})
),
addWebpackExternals(
{
// 不做打包处理配置,如直接以cdn引入的
'@antv/g2': 'window.G2',
"@antv/data-set": "window.DataSet",
}
),
(config) => {
config.output.publicPath = "http://bucket-11111111.cos.ap-nanjing.myqcloud.com/cdn/"
return config;
}
);
服务器下载COSCMD工具
- 服务器下载COSCMD工具
- 配置参数,设置SECRET_ID,SECRET_KEY,BucketName_appid(也就是存储桶名称),REGION
- 删除原先的打包后的文件(如果存在的话)
- 上传新的打包后的文件
官方文档关于COSCMD的介绍已经很详细了,笔者就不再复制粘贴了,第3、4步骤写到部署脚本中即可,如果使用的是Jenkins的话,可以参考以下代码
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'cnpm install'
sh 'npm run build'
}
}
stage('Deploy') {
steps {
sh 'rm -rf /var/www/html/*'
sh 'cp -R ./build/* /var/www/html'
sh 'coscmd delete cdn/static -f'
sh 'coscmd upload -r /var/www/html/static cdn/'
sh 'nginx -s reload'
}
}
}
}
最终效果
基本上可以在两秒左右完成加载。