现场测量web关键性能指标的最佳实践(翻译)

837 阅读9分钟

原文:web.dev/vitals-fiel…

能够测量和报告页面的真实性能对于诊断和改进性能是至关重要的。如果没有现场数据,就不可能确切地知道您对站点所做的更改是否真的达到了预期的效果。

许多流行的Real User Monitoring(RUM)分析提供商已经在他们的工具(以及许多其他Web Vitals)中支持核心Web Vitals指标。如果您当前使用的是这些RUM分析工具之一,那么您可以评估站点上的页面在多大程度上满足建议的核心Web关键点阈值,并防止将来出现倒退。

虽然我们建议使用支持核心Web Vitals指标的分析工具,但是如果您当前使用的分析工具不支持这些指标,那么您不一定需要切换。几乎所有的分析工具都提供了一种定义和测量自定义指标事件的方法,这意味着您可以使用当前的分析提供商来测量核心Web关键指标,并将其添加到现有的分析报告和仪表板中。

本指南讨论了使用第三方或内部分析工具测量核心Web Vitals指标(或任何自定义指标)的最佳实践。它也可以作为一个指南,分析供应商希望增加核心网络生命支持他们的服务。

使用自定义指标或事件

如上所述,大多数分析工具都允许您测量自定义数据。如果您的分析工具支持这一点,那么您应该能够使用此机制来测量每个核心Web关键指标。

在分析工具中测量自定义指标或事件通常分为三个步骤:

  • 在工具的管理中定义或注册自定义度量(如果需要)。(注意:并非所有分析提供商都要求提前定义自定义指标。)

  • 计算前端JavaScript代码中度量值的值。

  • 将度量值发送到您的分析后端,确保名称或标识与步骤1中定义的内容相匹配(如果需要,进行重复)。

对于步骤1和步骤3,您可以参考分析工具的文档以获取说明。对于步骤2,您可以使用webvitals JavaScript库来计算每个核心web vitals指标的值。

下面的代码示例显示了在代码中跟踪这些度量并将它们发送到分析服务是多么容易。

import {getCLS, getFID, getLCP} from 'web-vitals';

function sendToAnalytics({name, value, id}) {
  const body = JSON.stringify({name, value, id});
  // Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
  (navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
      fetch('/analytics', {body, method: 'POST', keepalive: true});
}

getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);

确保您可以报告分发

一旦您计算了每个核心Web Vitals指标的值并使用自定义指标或事件将其发送到您的分析服务,下一步就是构建一个显示已收集值的报告或仪表板。

为了确保你达到了推荐的核心Web关键点阈值,你需要你的报告在第75个百分位显示每个指标的值。

如果您的分析工具没有提供分位数报告作为内置功能,您可能仍然可以通过生成一个按升序列出每个度量值的报告来手动获取这些数据。生成此报告后,通过该报告中所有值的完整排序列表的75%的结果将是该度量的第75个百分位,无论您如何对数据进行分段(按设备类型、连接类型、国家/地区等)。

如果您的分析工具在默认情况下没有为您提供度量级别的报告粒度,那么如果您的分析工具支持自定义维度,您可能会获得相同的结果。通过为跟踪的每个度量实例设置唯一的自定义维度值,如果在报表配置中包含自定义维度,则应该能够生成按单个度量实例细分的报表。因为每个实例都有一个唯一的维度值,所以不会进行分组。

例如,以下柱状图是使用上述技术从Google Analytics生成的(因为Google Analytics在其任何标准报告中都不支持分位数报告)。使用Analytics Reporting API查询数据,并使用JavaScript数据可视化库显示:

提示:webvitals库为报告的每个度量实例提供一个ID,这使得在大多数分析工具中构建分布变得非常容易。有关详细信息,请参阅度量接口文档。

在正确的时间发送数据

一些性能指标可以在页面完成加载后计算,而其他性能指标(如CLS)则考虑页面的整个生命周期,只有在页面开始卸载后才是最终的。

但是,这可能会有问题,因为beforeunload和unload事件都不可靠(尤其是在移动设备上),而且不建议使用它们(因为它们可能会阻止页面符合Back-Forward缓存的条件)。

对于跟踪页面整个生命周期的度量,最好在visibilitychange事件期间发送度量值的当前值,只要页面的可见性状态更改为hidden。这是因为一旦页面的可见性状态更改为hidden,就不能保证该页面上的任何脚本能够再次运行。尤其是在移动操作系统中,浏览器应用程序本身可以关闭而不触发任何页面回调。

请注意,移动操作系统在切换选项卡、切换应用程序或关闭浏览器应用程序本身时通常会触发visibilitychange事件。它们还会在关闭选项卡或导航到新页面时触发visibilitychange事件。这使得visibilitychange事件比unloadbeforeunload事件更可靠。

抓住了! 由于某些浏览器错误,在某些情况下visibilitychange事件不会触发。如果您正在构建自己的分析库,那么了解这些bug是很重要的。请注意,web vitals JavaScript库确实解释了所有这些错误。

随时间监控性能#

一旦您更新了您的分析实现,以跟踪和报告核心Web Vitals指标,下一步就是跟踪您的站点的更改如何随着时间的推移影响性能。

更改版本#

跟踪更改的一种幼稚(最终也是不可靠的)方法是将更改部署到生产中,然后假设在部署日期之后收到的所有度量都对应于新站点,而在部署日期之前收到的所有度量都对应于旧站点。但是,任何数量的因素(包括HTTP、服务工作线程或CDN层的缓存)都可能阻止这项工作。

更好的方法是为每个已部署的更改创建一个唯一的版本,然后在分析工具中跟踪该版本。大多数分析工具都支持设置版本。如果没有,您可以创建一个自定义维度,并将该维度设置为您的部署版本。

运行实验#

您可以通过同时跟踪多个版本(或实验)进一步推进版本控制。

如果您的分析工具允许您定义实验组,请使用该功能。否则,可以使用自定义维度来确保每个度量值都可以与报表中的特定实验组相关联。

在分析中进行实验后,您可以对用户的子集进行实验性更改,并将更改的性能与控制组中用户的性能进行比较。一旦您确信某个更改确实提高了性能,您就可以将其推广到所有用户。

实验组应该总是设置在服务器上。避免使用在客户端上运行的任何实验或A/B测试工具。在确定用户的实验组之前,这些工具通常会阻止渲染,这可能会影响LCP时间。

确保测量不会影响性能#

在测量真实用户的性能时,绝对重要的是,您正在运行的任何性能度量代码都不会对页面的性能产生负面影响。如果是这样,那么您试图得出的关于您的性能如何影响您的业务的任何结论都将是不可靠的,因为您永远不知道分析代码本身是否具有最大的负面影响。

在生产站点上部署RUM分析代码时,请始终遵循以下原则:

推迟你的分析#

分析代码应该总是以异步、非阻塞的方式加载,并且通常应该最后加载。如果以阻塞方式加载分析代码,则会对LCP产生负面影响。

所有用于测量核心Web Vitals指标的api都是专门设计来支持异步和延迟脚本加载的(通过buffered标志),所以不必急于让脚本提前加载。

如果您正在度量一个在页面加载时间轴中无法计算的度量,则应该只将需要在文档的<head>中运行的代码内联(因此它不是呈现阻塞请求),并推迟其余的代码。不要因为一个指标需要就提前加载所有的分析。

不要创建长任务#

分析代码通常是响应用户输入而运行的,但是如果分析代码执行大量DOM测量或使用其他处理器密集型api,则分析代码本身可能会导致输入响应性较差。另外,如果包含分析代码的JavaScript文件很大,执行该文件可能会阻塞主线程并对FID产生负面影响。

使用非阻塞API#

非关键任务如sendBeacon()requestBeacon()是专门为非关键任务而设计的。

这些api是在RUM分析库中使用的很好的工具。

通常,所有分析信标都应该使用sendBeacon()API(如果可用)发送,并且所有被动分析度量代码都应该在空闲期间运行。

有关如何最大限度地利用空闲时间的指导,同时仍然确保代码可以在需要时紧急运行(例如当用户卸载页面时),请参考idle-until-emergent模式。

不要跟踪超过你需要的#

浏览器公开了大量的性能数据,但是仅仅因为这些数据是可用的并不意味着你应该记录这些数据并将其发送到你的分析服务器。

例如,资源计时API为页面上加载的每个资源提供详细的计时数据。但是,不太可能所有这些数据都对提高资源负载性能有必要或有用。

简言之,不要因为数据就在那里就跟踪它,要确保在消耗资源跟踪它之前使用这些数据。