记一次前端项目优化实战
前言
前几天接到某项目的一个前端问题,一个移动端的H5页面,用手机4G网打开加载要十几秒,长达十几秒的白屏让用户接受不了。第二天就跑去现场看了下问题,然后给这个项目做了一些优化,晚上回来就想着把这事给记下来整理成文档,希望能给大家在前端项目优化上有所帮助。
问题收集
在拿到代码还有去现场之前,就拿到了以下几个问题:
- 所有手机都会出现这个问题,我这边的三星,苹果还有客户的华为折叠屏都有这种情况。
- 安卓和ios在清理缓存重新打开应用后会出现这个问题。
- 这边的情况是在用4G网的情况下,清理手机缓存后有很大的几率会出现这个问题,这个问题是显示空白页面,无法显示内容,跟群里的截图一样。在用WiFi的情况下,清理手机缓存,然后再进应用第一次加载比较慢,但是能进去,跟前面的进不去问题不一样。
问题分析
拿到这几个问题之后我首先想到这几个点:
- 接口慢
- 网络慢
- 静态资源、js体积大导致加载慢
后来拿到url地址之后,我用微信开发者工具看了一下,这个微信开发者工具那来看移动端页面还是蛮方便的。我的电脑用的是WiFi(我这WiFi网速只有450k/s左右),发现加载确实有点慢,用了4s多。
然后我把网络切到Fast 3G,页面加载完花费了11s。
从图中可以看到,一个js文件达到了1.6M,WiFi下加载了4s多,问了下他们那边服务器有用到Gzip压缩,也就是说这个js原本比我们现在看到的还要大,然后找他们拿到了部署在服务器上的前端包,我发现这个js有4.8M。
看到这只能去拿代码分析了,我怀疑可能是引入了不必要的依赖导致的。
webpack插件:webpack-bundle-analyzer
分析代码之前,先讲一下这个东西,webpack-bundle-analyzer是一款webpack的可视化资源分析工具。它能够帮助我们真正的了解到包里的内容,并且能展示出各个模块在包里所占用的空间大小,最终能够帮助我们优化它。
安装依赖
# npm
$ npm install --save-dev webpack-bundle-analyzer
# yarn
$ yarn add -D webpack-bundle-analyzer
作为插件使用
在webpack.config.js中:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
在package.json的scripts里加入下面这条命令,就可以npm run build之后看到webpack-bundle-analyzer的效果:
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
运行npm run build后弹出的页面(官方效果图):
我们可以通过使用webpack-bundle-analyzer可以看到项目各模块的大小,可以按需优化。
分析代码
接下来我们看代码,这是用Chameleon框架开发的页面,刚好cml框架已经集成了webpack-bundle-analyzer功能,可以直接使用。
在chameleon.config.js
里web属性下面的dev和build里都加上analysis: true
来开启资源分析工具:
web: {
dev: {
analysis: true,
},
build: {
analysis: true,
publicPath: './',
},
}
这样在本地运行还有打包的时候都可以进行资源分析。
运行cml web dev
启动项目,启动成功后会跟上面讲的一样弹出这样一个页面:
当我看到@antv和ant-design-vue这两个依赖时我就感到非常困惑,这是一个移动端项目,我想怎么着也不会用到ant-design-vue和@antv这两个依赖吧,因为我还看到有用到vant这个移动端UI组件库,在项目中全局搜索了下这两个依赖,发现在app.cml这个文件中有import这两个依赖。
然而在这些地方引入之后,我在项目其他页面并没有发现有用到这两个依赖的任何内容,也就是说这俩依赖并没有被使用到,但是却在构建的时候被扔进了包里,然后这俩依赖就无缘无故的占用了一般的包大小。
在我注释掉这些没用的引用之后再次运行,通过分析页面可以看出这两个依赖就不存在了:
顺藤摸瓜,根据package.json的依赖列表进行逐一排查,依次去掉所有不必要的依赖引入。突然心血来潮,我用编辑器察看了下打包好的js文件,发现了一些被转成base64的图片,然后看了下Chameleon的文档,发现在引入静态资源目录里的图片时在url后面加上了?_inline会被转成base64。
由于时间原因,就只做了这两方面的优化,最终打出来的包体积也非常可观,只有800k左右:
再部署到服务器上使用Gzip压缩后页面加载速度还是很不错的:
写在最后
这次优化并没有完全做完,还有很多的点,例如vant组件在代码里是被全部引入的,可以改为按需引入,在代码里还有大量被import却没有使用的包,虽然最终不会压缩进js里,但还是建议去掉这些不必要的import。还有路由懒加载、图片压缩、删除未使用的CSS等等