以前一年多前接手的一个react项目,前段时间由于作业务中台项目,对公司现有的应用项目作中台化改造,这期间将项目部署到uat环境,
测试期间,测试小妹妹和产品大叔都吐槽进入uat项目的时候要load好久,白屏时间超过30s,体验不好,
生产不至于这么慢但也是白屏时间挺长的,因此减小白屏时间增长用户体验成为了当务之急。
复制代码
经过开发者工具能够看到白屏的主要缘由在于bundle.js这个打包后的文件过大,达到3.6M
加上uat环境带宽等问题的话,光加载这个bundle.js就花了30s+,因此白屏时间太长,用户体验差
要解决这个问题就得从这个bundle.js入手
复制代码
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const webpackConfigDev = { plugins: [ ...... new BundleAnalyzerPlugin({ analyzerPort: 3012 }), ] } 复制代码
这是本地开发时候打包的状况,没有gzip的状况下是这么大的,本地开发编译打包也是挺慢的
从上图看能够分析出几个比较大的模块,其中一个最大的是echarts,另外就是源文件src目录下的代码
因此优化分为三步来走:
1.优化echarts;
2.优化src下的业务代码;
3.对打包后的文件进行gzip压缩;
复制代码
echarts在项目中用到的地方很多,可是业务平时不多用到对应的模块,整个打包进去bundle.js只会让整个包变大
思路是echarts文件不打包进bundle.js,采用cdn的方法引入
复制代码
1.入口文件index.html这里直接用script直接引入cdn的echarts文件 <head> <meta charset="UTF-8"> <meta http-equiv="Cache-Control" content="max-age=604800" /> <script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script> <title>TCRM</title> </head> <body> 2.使用echarts的地方改成下面这样引入 原先的 var myChart = echarts.init(this.refs.char,'crm'); 改版后 var myChart = this.$echarts.init(this.refs.char,'crm'); 复制代码
对于用户来讲,可能每次操做的时候只操做对应的几个模块,其余模块不多操做到,若是可以按需加载那就能够化整为零
每次加载当前模块的chunk,既不影响用户使用,又减小加载的资源
参考了一下其余文章,决定采用react-loadable进行切割划分,按路由来切割资源
复制代码
原先写法,组件引入 import Dashboard from './components/Dashboard'; 使用react-loadable后 import Loadable from 'react-loadable'; const LoadingFun = () => { return <div className="center-div"><Spin spinning={true} size="large" tip="加载中..."/></div>; }; const Dashboard = Loadable({loader: () => import('./components/Dashboard'), loading: LoadingFun}); webpack相关 const webpackConfigBase = { ...... output: { path: resolve('./dist'), filename: 'bundle.[hash:6].js', chunkFilename: 'chunks/[name].[hash:6].js', } } 复制代码
本地运行分chunks打包 javascript
1.打包样式问题,全部的css打包到bundle.css中,可是采用按路由打包后测试的小妹妹反馈样式很奇怪 看了一下加载的资源,发现确实没有打包到不一样路由下的样式,检查了一下,发现是webpack配置里面要配合改一下 const webpackConfigBase = { ...... plugins: [ // 提取css //原先的 new ExtractTextPlugin('bundle.[hash:6].css'), new ExtractTextPlugin({filename: 'bundle.[hash:6].css', allChunks: true}), // 增长一个allChunks:true ] } 2.chunk的名字问题,先要指定对应的chunkName参考 https://github.com/mrdulin/blog/issues/43 复制代码
项目是用的nginx作代理调用打包后的资源,因此能够考虑在nginx这一层增长配置配合gzip文件
复制代码
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 9; 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_vary on; 复制代码
echarts经过cdn引入,成功
bundle.js体积大大减少,加载时间也由原先的30s+降到了3s+,生产环境带宽更高会更快,成功
切换路由加载对应的chunk文件,使用正常,成功
复制代码
经过cdn引入echart中原先的写法会读取不到echart的资源,排查了一下从新作了修改 能够在控制台模拟是否能获取到echart的方法进行调试 原先的 var myChart = this.$echarts.init(this.refs.char,'crm'); 改版后 var myChart = window.echarts.init(this.refs.char,'crm'); 复制代码