记一次前端项目优化实战

less than 1 minute read

前言

前几天接到某项目的一个前端问题,一个移动端的H5页面,用手机4G网打开加载要十几秒,长达十几秒的白屏让用户接受不了。第二天就跑去现场看了下问题,然后给这个项目做了一些优化,晚上回来就想着把这事给记下来整理成文档,希望能给大家在前端项目优化上有所帮助。

问题收集

在拿到代码还有去现场之前,就拿到了以下几个问题:

  • 所有手机都会出现这个问题,我这边的三星,苹果还有客户的华为折叠屏都有这种情况。
  • 安卓和ios在清理缓存重新打开应用后会出现这个问题。
  • 这边的情况是在用4G网的情况下,清理手机缓存后有很大的几率会出现这个问题,这个问题是显示空白页面,无法显示内容,跟群里的截图一样。在用WiFi的情况下,清理手机缓存,然后再进应用第一次加载比较慢,但是能进去,跟前面的进不去问题不一样。

问题分析

拿到这几个问题之后我首先想到这几个点:

  • 接口慢
  • 网络慢
  • 静态资源、js体积大导致加载慢

后来拿到url地址之后,我用微信开发者工具看了一下,这个微信开发者工具那来看移动端页面还是蛮方便的。我的电脑用的是WiFi(我这WiFi网速只有450k/s左右),发现加载确实有点慢,用了4s多。

image-20200807000002229

然后我把网络切到Fast 3G,页面加载完花费了11s。

image-20200807000151218

从图中可以看到,一个js文件达到了1.6M,WiFi下加载了4s多,问了下他们那边服务器有用到Gzip压缩,也就是说这个js原本比我们现在看到的还要大,然后找他们拿到了部署在服务器上的前端包,我发现这个js有4.8M。

image-20200807001417531

看到这只能去拿代码分析了,我怀疑可能是引入了不必要的依赖导致的。

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后弹出的页面(官方效果图):

93f72404-b338-11e6-92d4-9a365550a701.gif

我们可以通过使用webpack-bundle-analyzer可以看到项目各模块的大小,可以按需优化。

分析代码

接下来我们看代码,这是用Chameleon框架开发的页面,刚好cml框架已经集成了webpack-bundle-analyzer功能,可以直接使用。

chameleon.config.js里web属性下面的dev和build里都加上analysis: true来开启资源分析工具:

web: {
  dev: {
    analysis: true,
  },
  build: {
    analysis: true,
    publicPath: './',
  },
}

image-20200807221741430

这样在本地运行还有打包的时候都可以进行资源分析。

运行cml web dev启动项目,启动成功后会跟上面讲的一样弹出这样一个页面:

image-20200807223020644

当我看到@antv和ant-design-vue这两个依赖时我就感到非常困惑,这是一个移动端项目,我想怎么着也不会用到ant-design-vue和@antv这两个依赖吧,因为我还看到有用到vant这个移动端UI组件库,在项目中全局搜索了下这两个依赖,发现在app.cml这个文件中有import这两个依赖。

image-20200807225308228

image-20200807225331352

image-20200807225352186

image-20200807225432399

然而在这些地方引入之后,我在项目其他页面并没有发现有用到这两个依赖的任何内容,也就是说这俩依赖并没有被使用到,但是却在构建的时候被扔进了包里,然后这俩依赖就无缘无故的占用了一般的包大小。

在我注释掉这些没用的引用之后再次运行,通过分析页面可以看出这两个依赖就不存在了:

image-20200807230619704

顺藤摸瓜,根据package.json的依赖列表进行逐一排查,依次去掉所有不必要的依赖引入。突然心血来潮,我用编辑器察看了下打包好的js文件,发现了一些被转成base64的图片,然后看了下Chameleon的文档,发现在引入静态资源目录里的图片时在url后面加上了?_inline会被转成base64。

image-20200807232352886

由于时间原因,就只做了这两方面的优化,最终打出来的包体积也非常可观,只有800k左右:

image-20200807232741729

再部署到服务器上使用Gzip压缩后页面加载速度还是很不错的:

image-20200807232938491

写在最后

这次优化并没有完全做完,还有很多的点,例如vant组件在代码里是被全部引入的,可以改为按需引入,在代码里还有大量被import却没有使用的包,虽然最终不会压缩进js里,但还是建议去掉这些不必要的import。还有路由懒加载、图片压缩、删除未使用的CSS等等