前端感官性能的衡量和优化实践
本文已发表在2017年8月《程序员》杂志。
我们为什么需要关注站点的性能,性能为什么如此重要呢?如今任何互联网产品首先重要的都是流量,流量最终会转换为商业价值。所以在互联网产品中,流量、转化率和留存率基本上是产品经理或者业务非常关注的几个因素,而性能则会直接影响到用户的转化和留存(在一定阶段之后影响较大,产品初期功能的因素占比更大)。所以换言之性能,其实是钱,我们关注和监测性能并非是为了数据而数据。产品的使用体验我认为包含三大要素:产品功能、交互视觉、前端性能,而我们做性能优化的最终目的是提升前端性能,从而提升产品体验。
传统性能优化
值得庆幸的是,前端的性能优化有诸多有迹可循的理论和方法,比如 Yahoo!性能军规(Best Practices for Speeding Up Your Web Site)、Google PageSpeed Insights Rules(https://developers.google.com/speed/docs/insights/rules)。万变不离其宗,诸如此类的性能优化准则都可以对应到 Browser Processing Model 的不同阶段。
图 1 浏览器的加载和处理过程
根据图 1 的 Processing Model,我们可以统计得到以下性能指标:
redirect: timing.fetchStart - timing.navigationStartdns: timing.domainLookupEnd - timing.domainLookupStartconnect: timing.connectEnd - timing.connectStartnetwork: timing.connectEnd - timing.navigationStartload: timing.loadEventEnd - timing.navigationStartdomReady: timing.domContentLoadedEventStart - timing.navigationStartinteractive: timing.domInteractive - timing.navigationStartttf: timing.fetchStart - timing.navigationStartttr: timing.requestStart - timing.navigationStartttdns: timing.domainLookupStart - timing.navigationStartttconnect: timing.connectStart - timing.navigationStartttfb: timing.responseStart - timing.navigationStartfirstPaint: timing.msFirstPaint - timing.navigationStart
这些指标对于前端而言都司空见惯,基本上核心关注的无外乎是:首字节时间(用于衡量网络链路和服务器响应性能)、白屏时间(firstPaint)、可交互时间(interactive)、完全加载时间(load)。我们在很长一段时间里都是根据这些指标来量化分析我们的站点性能,似乎不曾认真想过这些指标是否能够真正的反映用户的感官性能。
显然,这些指标绝大部分都属于非视觉指标(Non-Visual Metrics),是体验优化的常规指标,更是体验和性能优化中逃不开的关键因素,但却并非感官指标,也并不能完全衡量出用户的感官性能(Perceptual Performance)。
感官性能优化
所谓感官性能,即用户直观感知到的性能,用户感受是一种非常主观的判断,那么如何衡量和统计感知性能?通常我们针对用户感知会通过用研分析的方式(眼动仪、用户沟通、用户反馈、调研问卷、专家评估)来评估和衡量。但感官性能不同于用户感受,是否有方式可以量化和衡量呢?笔者经过一些调研和了解后,发现感官性能是可以通过一定方式进行衡量、分析和对标的,因为对性能的感受更多反映在视觉的变化上,因此我们可以通过一些视觉指标来衡量感官性能:
First Paint TimeFirst Contentful Paint TimeFirst Meaningful Paint TimeFirst Interactive TimeConsistently Interactive TimeFisrt Visual ChangeLast Visual ChangeSpeed IndexPerceptual Speed Index
First Paint 又称之为 First Non-Blank Paint,表示文档中任一元素首次渲染的时间。First Contentful Paint 代表文档中内容元素(文本、图像、Canvas,或者 SVG)首次渲染的时间。它通常情况下是无意义的渲染,比如头部和导航条。First Meaningful Paint Time 代表首次有意义的渲染时间(它的统计在重大的布局变化之后,往往代表了用户所关心的首次渲染时间),First Interactive Time、Consistently Interactive Time 分别表示首次可交互时间和持续可交互时间。
如图 2 的流程图展示了 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 的算法如下,它代表了我们页面在加载过程中视觉上的变化速度,其值越小代表感官性能越好:
公式 1
通过 FCP(First Contentful Paint)、FMP(First Meaningful Paint)、PSI(Perceptual Speed Index),我们可以实现跨平台的感官性能分析和对标(比如可以实现 HTML5 和 Hybrid 对比,HTML5 和原生应用的对比等),如图 3 所示为我们项目中某列表页的 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 完全可以进行全面的性能体验和分析,已经能够为我们的优化提供足够多的指导建议。
感官性能的跨平台对标
仅仅在开发阶段拥有可用的分析检测工具还远远不够,通常情况下,我们更希望在产品上线后,和竞对的产品进行感官性能的对标分析,而这里往往会涉及到跨平台(因为竞对的产品实现可能是通过 HTML5 实现,也可能是诸如 Weex、React Native 的混合开发形式,当然还有很大一部分可能是原生的实现)。
如何进行跨平台的感官性能对标,在笔者看来非常重要,现在行业内大家普遍采用的对标方式是视频对比,通过两个视频的时间轴对比来说明感官性能的提升。个人认为这种方式无法做到量化和自动化,因此可能会出现不同的人对比得出的结果并不能够对齐,同时效率较低。
我们需要做的仅仅是更进一步,将视频对比的过程量化和自动化。因此笔者在充分调研了现有社区的一些实现后,和同事封装了一个简单易用的小工具(Twilight)用于感官性能的跨平台对标。我们需要做的仅仅是录制视频,然后点选关键帧,之后便能够自动的将 SI(Speed Index)、PSI(Perceptual Speed Index)、FVC(First Visual Change)、FCP(FirstContentful Paint)、FMP(First Meaningful Paint)、LVC(Last Visual Change)等指标可视化的呈现出来。
图 4 使用 Twilight 分析工具获取感官性能指标的流程
业务应用优化实践
在业务项目上我们也针对国际机票进行了一系列的摸索和实践。国际机票在客户端内以及纯浏览器中都可能被访问,采用了 Vue 2.0 作为基础框架,并通过纯静态化的方式开发并部署至 CDN。起初国际机票的页面加载白屏明显(首次内容渲染时间长),用户体验较差。因此我们通过上述提到的一些工具进行了分析,发现网络请求、应用启动、接口请求是影响列表页性能加载的三大因素。
针对上述问题,我们采用了以下关键的优化策略:
纯前端离线化(在浏览器中通过纯前端的手段进行资源文件的离线化);客户端离线化(在客户端容器内通过离线包的方式实现资源文件及页面的离线化);页面组件化并按需加载(通过组件化方式对页面细粒度拆分并按需加载);预渲染提升感官性能(在框架启动之前,通过预渲染的方式确保页面框架最快呈现)。
通过上述优化策略优化后,效果显著,纯前端离线化上线后可交互和完全加载时间提升 50%,客户端离线化上线后,首字节时间基本为 0(降低 500 毫秒),可交互和完全加载时间相较纯前端离线化进一步提升 30%至 50%,按需加载和预渲染上线后页面的 FMP(First Meaningful Paint)提升 80%。
如图 5 所示为列表页在 Chrome 浏览器中模拟 4G 并将 CPU 模拟 4 倍降速(CPU Throttling 4x slowdown)的表现(不包含客户端离线化的效果)。
图 5 国际机票项目性能优化前后的加载效果对比
性能分析及优化小结
总结一下,前端的性能分析和优化方式,无论是传统性能还是感官性能完全有迹可循。开发阶段可以使用 Dev Tools、Lighthouse,借助非视觉指标(Non-Visual Metrics)和视觉指标(Visual Metrics)进行分析,遵循传统性能优化军规以及 Google PRPL Pattern 进行性能优化。通过我们提供的工具 Twilight 可以便捷的实现感官性能的跨平台对标分析。虽然我们在业务项目中的实践取得了一定的效果,但优化之路漫漫,还有很多空间的可能性。欢迎对性能优化感兴趣的同行一同交流,Do Better Web。
作者简介
郭凯,美团点评酒旅前端高级技术专家、高级技术经理,目前负责美团点评酒旅事业群境内度假终端研发团队,致力于终端技术体系的完善和基础设施的建设,培养人才精进团队,服务业务创造科技价值,译作有《编写可维护的 JavaScript》、《第三方 JavaScript 编程》等。
下一章:人工智能在线特征系统中的生产调度
前言: 在上篇博客《人工智能在线特征系统中的数据存取技术》中,我们围绕着在线特征系统存储与读取这两方面话题,针对具体场景介绍了一些通用技术,此外特征系统还有另一个重要话题:特征生产调度。本文将以美团点评酒 ...