性能优化
生产环境性能优化
操作
打开隐身模式,防止浏览器插件影响数据,清理内存,关闭浏览器缓存,打开 Screenshots 查看页面加载情况
进入首页,开始记录
分析数据
lighthouse面板数据: FP
DCL 7.23秒
FCP 6.6 - 8.3 秒
LCP 9.13 - 13 秒
performance面板数据: FCP 2.1-3秒 LCP 2.2-3.6秒
分析耗时构成
脚本执行时间Scripting 385 毫秒 System 耗时 223 毫秒 渲染 Render 耗时 69 毫秒 绘制 Painting 14 毫秒
总共耗时 12.242 秒
可知大部分耗时在于网络加载 分析网络线程:
DCL 7.23 秒,之前主要是加载静态资源,需要加载不少
html 文件 4.8 KB 总耗时 568毫秒,主要耗费在等待服务器响应 552毫秒 app.contenthash.js 文件 1.2 MB 主要耗时在下载静态资源 1.77 秒 chunk.vendors.contenthash.js 第三方库 6MB 主要耗时在下载静态资源 6.17 秒
DCL 到 FCP 之间耗时 1 秒
主要耗时在 一个影响全局配置的全局接口,200ms,主要时间花在等待服务器响应,等待了160ms home 页面静态 js 资源加载和渲染, 主要耗时在加载 3个 js 资源,三个资源并行加载,最长的耗时在 650ms(等待服务器响应250ms + 下载耗时 400ms)
FCP 到 LCP 耗时 1 秒,主要耗时在图片资源下载(主要耗费时间在等待服务器响应每个都在500ms,然后最大的一张图片下载需要差不多500ms)
优化方案
可以看到服务器的响应时间过长,每次发请求基本上等待服务器响应,都普遍在 160 ms-500 ms之间,最长的一些prefetch的js文件还有700+ms的,这个属于网络问题,可以使用对于首屏性能优化,可以使用
- CDN,内容分化网络,第三方的 CDN 服务一般网速比较快,而且站点分布的比较多,有限获取最近的服务器,从而提高访问速度
- 升级 http2:有服务器推送,对于需要的资源提前推送给浏览器,浏览器收到推送后,会自动下载,从而减少请求数,从而提高性能;请求头压缩;多路复用 ( http1.1最多6个连接 )。
不是首屏的话,开启缓存,需要注意对html文件开启 no-cache(每次进行协商缓存), 然后 js 文件使用 content-hash 模式,同时开启强缓存和协商缓存(一般使用 nginx 的话,默认时开启的)
js 文件过大的时候,做的:
- 代码分割,使用 http2 的话,可以尽可能细粒度分割代码
- 懒加载
- 按需加载
- 静态资源压缩,nginx 开启 gzip
- tree shaking
- 去除冗余代码,删除注释代码
不是首屏的话,和上面一样可以开启缓存
图片优化:
- 减少图片大小:改变图片的格式(webp兼容新还可以);压缩图片,使用特殊压缩工具来压缩图片的大小,不失真。
- 懒加载:进入视野的时候才加载,使用图片自带的 lazyload,或者 vue 指令,第三方库都可以
- 预加载:在空闲的时候提前获取(服务器推送,首屏可能用不到)
- 减少图片数量,一些图片(业界一般选小于8KB的)可以直接使用 base64,嵌入到 html中,避免发送请求
- 放 CDN
- 先加载低质量的图片,等加载完成再替换成高清图片
不得不说
开发环境性能优化
使用 source-map 的时候优先使用 cheap-module-eval-source-map
使用开发缓存
实操
打开无痕浏览器,打开页面,去lighthouse,选择 desktop,禁止缓存,开始分析
打开网络面板
打开coverage面板
数据
查看 FCP 6.6,LCP 10.9
分析
查看主要耗时: 静态资源 最大图片元素加载 8S 进入首页前有 一个全局配置接口耗时 首页有一个耗时的一次获取所有首页图片接口base64的接口
主要js文件加载耗时: app.js 文件 1.2 MB 公共包文件 6.3 MB 另一个chunk文件 0.6 MB
使用 coverage 查看代码覆盖情况,发现 app.js首屏未使用率51% 公共包文件未使用率 41%
优化
去除全局接口中无用的数据,压缩字段长度
首页获取所有图片base64图片的接口改为获取图片链接,直接流式读取文件。
优化静态资源加载
图片优化:
png 替换为 webp,并压缩图片,使用 picture 标签来保底,图片懒加载
最大图片先给一个低质量图片,等加载完成再替换成高清图片
代码优化:
通过coverage知道有很多代码没使用,但是不知道那些没使用,使用可视化插件工具来对打包后的代码进行可视化,从而知道哪些代码没使用,然后进行优化。
对没有使用的包进行删除。如果实在找不到为啥有个包打包进来了,使用 npm ls 命令查看,依赖关系,精准定位项目依赖,例如打包进去了@antv/g2,但是项目根本没有用到,就可以找到什么包依赖了这个包,如果这个包也没有用到就可以删除了。
开启 gzip
优化后: FCP 1.5秒 LCP 3.1秒 加载js资源 1.2 MB