前端感官性能的衡量和优化实践
对于前端而言,性能和体验优化是亘古不变的话题。——题注
前端(Front-End)行业自从互联网出现后迅猛发展,从最初实现网页特效到如今的的富应用、混合开发、乃至大型互联网应用的开发,从当初的脚本语言发展至今成为一门当之无愧的开发语言,更可谓是从农耕时代步入到了工业时代。随之而来前端面临的挑战也越来越多,诸如性能体验、工程效率、甚至服务运维的问题对于前端而言已经不是什么新鲜话题了。
本文旨在讨论如何衡量用户的感官性能,以及如何实现感官性能的跨平台对标。笔者曾就职过音悦台、淘宝旅行,如今就职于美团点评酒旅事业群,期间开发过也接触过不少面向用户的C端项目,性能和体验这两个关注点基本上是用户端项目的标配,因此“开发-上线-监控-性能优化-上线-监控…”成了用户端项目的常见开发流程。
我们为什么需要关注站点的性能,性能为什么如此重要呢?如今任何互联网产品首先重要的都是流量,流量最终会转换为我们的商业价值。所以在互联网产品中,流量、转化率和留存率基本上是产品经理或者业务非常关注的几个因素,而性能则会直接影响到用户的转化和留存(在一定的阶段之后影响较大,产品初期功能的因素占比更大)。所以换言之性能其实是钱,我们关注和监测性能并非是为了数据而数据。产品的使用体验我认为包含三大要素:产品功能、交互视觉、前端性能,而我们做性能优化的最终目的是提升前端性能,从而提升产品体验。
传统性能优化
值得庆幸的是,前端的性能优化有诸多有迹可循的理论和方法,比如Yahoo性能军规,再比如Google PageSpeed Insights Rules。万变不离其宗,诸如此类的性能优化准则都可以对应到Browser Processing Model的不同阶段。
图1 浏览器的加载和处理过程
根据以上Processing Model,我们可以统计得到以下性能指标:
- redirect: timing.fetchStart - timing.navigationStart
- dns: timing.domainLookupEnd - timing.domainLookupStart
- connect: timing.connectEnd - timing.connectStart
- network: timing.connectEnd - timing.navigationStart
- load: timing.loadEventEnd - timing.navigationStart
- domReady: timing.domContentLoadedEventStart - timing.navigationStart
- interactive: timing.domInteractive - timing.navigationStart
- ttf: timing.fetchStart - timing.navigationStart
- ttr: timing.requestStart - timing.navigationStart
- ttdns: timing.domainLookupStart - timing.navigationStart
- ttconnect: timing.connectStart - timing.navigationStart
- ttfb: timing.responseStart - timing.navigationStart
- firstPaint: timing.msFirstPaint - timing.navigationStart
这些指标对于前端而言都司空见惯,基本上核心关注的无外乎是:首字节时间(用于衡量网络链路和服务器响应性能),白屏时间(firstPaint),可交互时间(interactive),完全加载时间(load)。我们在很长一段时间里都是根据这些指标来量化分析我们的站点性能,似乎不曾认真想过这些指标是否能够真正的反应用户的感官性能。
显然,这些指标其实绝大部分都属于非视觉指标(Non-Visual Metrics),是体验优化的常规指标,更是体验和性能优化中逃不开的关注因素,但却并非感官指标,也并不能完全衡量出用户的感官性能(Perceptual Performance)。
感官性能优化
所谓感官性能,即用户直观感知到的性能,用户感受是一种非常主观的判断,那么如何衡量和统计感知性能?通常我们针对用户感知会通过用研分析的方式(眼动仪、用户沟通、用户反馈、调研问卷、专家评估)来评估和衡量。但感官性能不同于用户感受,是否有方式可以量化和衡量呢?笔者经过一些调研和了解后,发现感官性能是可以通过一定方式进行衡量、分析和对标的,因为对性能的感受更多反映在视觉的变化上,因此我们可以通过一些视觉指标来衡量感官性能:
- First Paint Time
- First Contentful Paint Time
- First Meaningful Paint Time
- First Interactive Time
- Consistently Interactive Time
- Fisrt Visual Change
- Last Visual Change
- Speed Index
- Perceptual Speed Index
First Paint又称之为First Non-Blank Paint,表示文档中任一元素首次渲染的时间。First Contentful Paint代表文档中内容元素(文本、图像、Canvas,或者SVG)首次渲染的时间。它通常情况下是无意义的渲染,比如头部和导航条。First Meaningful Paint Time代表首次有意义的渲染时间(它的统计在重大的布局变化之后,往往代表了用户所关心的首次渲染时间),First Interactive Time、Consistently Interactive Time分别表示首次可交互时间和持续可交互时间。
下面的流程图展示了Blink内核中Time-to-first-X-paint的分析原理和上报路径(其它first-X-paint的指标类似)。
图2 Blink内核中Time-to-first-X-paint的分析原理和上报路径
Fisrt Visual Change、Last Visual Change分别表示首次和最后一次视觉发生变化的时间点,Speed Index、Perceptual Speed Index均为视觉速度,两者的区别在于背后所用到的算法不同,前者采用了Mean Pixel-Histogram Difference算法,后者则采用了Structural Similarity Image Metric算法,其中Perceptual Speed Index的统计结果更贴近用户的真实感受。Speed Index的算法如下,它代表了我们页面在加载过程中视觉上的变化速度,其值越小代表感官性能越好:
\[Index = \int_{start}^{end} 1-\frac{Visual Complete}{100}dt\]通过FCP(First Contentful Paint)、FMP(First Meaningful Paint)、PSI(Perceptual Speed Index),我们可以实现跨平台的感官性能分析和对标(比如可以实现H5和Hybrid对比,H5和原生应用的对比等),下图为我们项目中某列表页的SI和PSI柱状图。
图3 业务项目中某列表页的SI和PSI柱状图示意
性能优化分析工具
提及性能优化分析工具,在开发阶段我们拥有众多的选择(比如Chrome自带的Dev Tools,老牌的YSlow,以及Google推出的PageSpeed Insights),这里笔者强烈推荐的是Lighthouse,Lighthouse是一个开源的自动化工具,运行Lighthouse的方式有两种:作为Chrome扩展程序运行,或作为命令行工具运行。 Chrome扩展程序提供了一个对用户更友好的界面,方便读取报告。命令行工具允许您将Lighthouse集成到持续集成系统。
通过Lighthouse我们可以对页面从PWA、性能、可访问性、最佳实践几个方面进行多维度的分析,并给出结果和建议,上文中提到的FMP(First Meaningful Paint)、FI(First Interactive),CI(Consistently Interactive),PSI(Perceptual Speed Index)都可以从其中的性能报告中分析得到。
由于篇幅所限,对于Lighthouse的细节说明、原理及使用在此不再赘述,基本上在开发阶段通过Chrome Dev Tools、Lighthouse完全可以进行全面的性能体验和分析,已经能够为我们的优化提供足够多的指导建议。
感官性能的跨平台对标
仅仅在开发阶段拥有可用的分析检测工具还远远不够,通常情况下,我们更希望在我们的产品上线后,和竞对的产品进行感官性能的对标分析,而这里往往会涉及到跨平台(因为竞对的产品实现可能是通过H5实现,也可能是诸如Weex、RN的混合开发形式,当然还有很大一部分可能是原生的实现)。
如何进行跨平台的感官性能对标,在我看来非常重要,现在行业内大家普遍采用的对标方式是视频对比,通过两个视频的时间轴对比来说明感官性能的提升。在笔者看来这种方式无法做到量化和自动化,因此可能会出现不同的人对比得出的结果并不能够对齐,同时效率较低。
我们需要做的仅仅是更进一步,将视频对比的过程量化和自动化。因此笔者在充分调研了现有社区的一些实现后,和同事封装了一个简单易用的小工具(Twilight)用于感官性能的跨平台对标。我们需要做的仅仅是录制视频,然后点选关键帧,之后便能够自动的将SI(Speed Index)、PSI(Perceptual Speed Index)、FVC(First Visual Change)、FCP(First Contentful Paint)、FMP(First Meaningful Paint)、LVC(Last Visual Change)等指标可视化的呈现出来。
图4 使用Twilight分析工具获取感官性能指标的流程
业务应用优化实践
在业务项目上我们也针对国际机票进行了一系列的摸索和实践。国际机票在客户端内以及纯浏览器中都可能被访问,采用了Vue2.0作为基础框架,并通过纯静态化的方式开发并部署至CDN。起初国际机票的页面加载白屏明显(首次内容渲染时间长),用户感受较差。因此我们通过上述提到的一些工具进行了分析,发现网络请求、应用启动、接口请求是影响列表页性能加载的三大因素。
针对上述问题,我们采用了以下关键的优化策略:
- 纯前端离线化(在浏览器中通过纯前端的手段进行资源文件的离线化)
- 客户端离线化(在客户端容器内通过离线包的方式实现资源文件及页面的离线化)
- 页面组件化并按需加载(通过组件化方式对页面细粒度拆分并按需加载)
- 预渲染提升感官性能(在框架启动之前,通过预渲染的方式确保页面框架最快呈现)
通过上述优化策略优化后,效果显著,纯前端离线化上线后可交互和完全加载时间提升50%,客户端离线化上线后,首字节时间基本为0(降低500毫秒),可交互和完全加载时间相较纯前端离线化进一步提升30%至50%,按需加载和预渲染上线后页面的FMP(First Meaningful Paint)提升80%。
下图为列表页在Chrome浏览器中模拟4G并将CPU模拟4倍降速(CPU Throttling 4x slowdown)的表现(不包含客户端离线化的效果):
图5 国际机票项目性能优化前后的加载效果对比
性能分析及优化小结
虽然我们在业务项目中的实践取得了一定的效果,但优化之路漫漫,还有很多空间可能性。欢迎对性能优化感兴趣的同行一同交流,Do Better Web。以下是笔者在调研和项目实践过程中的一点心得和总结。前端的性能分析和优化方式,无论是传统性能还是感官性能完全有迹可循。开发阶段可以使用Dev Tools、Lighthouse,借助非视觉指标(Non-Visual Metrics)和视觉指标(Visual Metrics)进行分析,遵循传统性能优化军规以及Google PRPL Pattern进行性能优化。通过我们提供的工具Twilight可以便捷的实现感官性能的跨平台对标分析。
作者简介:郭凯,美团点评酒旅前端高级技术专家、高级技术经理,于2014年7月入职美团,目前负责大交通和基础服务平台前端团队,致力于前端技术体系的完善和基础设施的建设,译作有《编写可维护的JavaScript》、《第三方JavaScript编程》、《JavaScript开发框架权威指南》,对跨终端跨平台开发有浓厚的兴趣。