1. 背景介绍
hubble平台是陌陌内部的一个监控平台,hubble的前端项目采用Vue+Echarts+ElementUI编写,是典型的单页面应用。
随着项目的长期迭代导致项目体积愈来愈大,打开首屏速度缓慢,为了提升用户体验,了解用户的真实使用情况,引入了google推荐的页面性能指标测量sdk web-vitals, 并着重优化了LCP指标。
2. 什么是LCP?
根据W3C Web性能工作组的讨论和Google的研究,发现度量页面主要内容的可见时间有一种精准且简单的方法,就是查看 “绘制面积” 最大的元素何时开始渲染。所谓绘制面积可以理解为每个元素在屏幕上的 “占地面积”,如果元素延伸到屏幕外,或者元素被裁切了一部分,被裁切的部分不算入在内,只有真正显示在屏幕里的才算数。最大内容绘制 (LCP, Largest Contentful Paint) 指标会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。因此能更真实的反馈用户实际体验。
3. 哪些因素会影响LCP
根据google的研究可以得到影响LCP主要有以下三个因素:
-
服务器响应速度缓慢
-
资源加载时间
-
JavaScript 和 CSS 渲染阻塞
因此根据上述几个因素,展开了LCP的优化
4. 优化过程
4.1 服务器响应速度缓慢
浏览器从服务器接收内容所需的时间越长,在屏幕上渲染任何内容所需的时间就越长。服务器响应速度变快就能直接提升LCP。
于是我做了如下优化:
-
对于响应较慢的、使用频次较高的接口进行优化,主要是将变化较少的数据添加缓存、耗时较大的统计查询交由定时任务计算等。
-
配合SA升级http协议到HTTP2.0来提升响应速度,这部分的提升主要来源于协议升级带来的新特性:多路复用、标头压缩等 ( 扩展阅读:/web/fundamentals/performance/http2?hl=zh-cn )
4.2 资源加载时间
对于大部分网站的最大元素都是图片、视频等资源,如果能加速这些图片的加载,能有效改善LCP。但是对于hubble来说这部分资源几乎没有,因此也就无需做相关优化。
4.3 JavaScript 和 CSS 渲染阻塞
在浏览器渲染任何内容之前,需要解析html,并生成dom树。html解析器会被任何同步脚本<script src=""> 阻塞并暂停解析。因此阻塞渲染的时间也就成为优化的重点,具体工作分为如下两个方面:
-
延迟加载未使用的js文件
-
最小化并压缩js文件
4.3.1 延迟加载未使用的js文件
优化前hubble的项目打包分为两个文件(包含业务逻辑)4.3M大小、(包含外部依赖如 Echarts(绘制曲线)、ElementUI(提供表格等常用组件)等)2.8M大小,浏览器需要等待这两个js都下载好进行下一步渲染,所以这部分耗时取决于最大的js包的大小,找到了这部分优化的重点就开始着手优化,通过vue的路由懒加载机制,将按照使用频次、功能模块拆分成多个较小的js文件,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
4.3.2 最小化并压缩js文件
在优化好了后发现,现在最大的js包是,依旧采用拆分的逻辑把拆成了、、等。随后发现原生的包过于大,且很多绘图功能对于hubble看说是没有必要的,使用echarts官方的在线定制功能,仅选择了hubble需要的功能,最终构建出的依赖包从原始的1.7M降低至689KB提升明显,最后在启用gzip压缩,能将文件在传输过程中进一步压缩,至此完成优化。
5. 最终效果
最终hubble的首次加载所需的最大js包由4.3M(gzip压缩后1.7M)缩小到现在的1.5M(gzip压缩后365kb),首次加载该js包耗时由1.82s降低至403ms(在办公网下测试,此结果受网络因素影响),LCP的P90指标从3.5s降低至1.78s,hubble首屏加载速度得到明显提升。
参考资料
[1] web-vitals一种用于衡量页面性能的工具 /learn-web-vitals/
[2] Largest Contentful Paint 最大内容绘制 (LCP) /lcp/
[3] HTTP/2简介 /web/fundamentals/performance/http2?hl=zh-cn
[4] vue路由懒加载 /zh/guide/advanced/
[5] Echarts 在线构建 /zh/