

# CloudWatch RUM Web 客户端收集的信息
<a name="CloudWatch-RUM-datacollected"></a>

本节将记录 **PuTrumEvent** 架构，其定义了可以使用 CloudWatch RUM 从用户会话中收集的数据结构。

**PuTrumEvent** 请求将包含以下字段的数据结构发送到 CloudWatch RUM。
+ 此批次 RUM 事件的 ID
+ 应用程序监控详细信息，包括以下内容：
  + 应用程序监控 ID
  + 受监控的应用程序版本
+ 用户详细信息，包括以下内容。**只有应用程序监控启用 Cookie 时才会收集此信息。**
  + Web 客户端生成的用户 ID
  + 会话 ID
+ 此批次中的 [RUM 事件](#CloudWatch-RUM-datacollected-event)数组。

## RUM 活动架构
<a name="CloudWatch-RUM-datacollected-event"></a>

每个 RUM 事件的结构均包含以下字段。
+ 事件 ID
+ 时间戳
+ 事件类型
+ 用户代理
+ [Metadata](#CloudWatch-RUM-datacollected-metadata)
+ [RUM 事件详细信息](#CloudWatch-RUM-datacollected-eventDetails)

## RUM 事件元数据
<a name="CloudWatch-RUM-datacollected-metadata"></a>

元数据包括页面元数据、用户代理元数据、地理位置元数据和域元数据。

### 页面元数据
<a name="CloudWatch-RUM-datacollected-metadata-page"></a>

页面元数据包括以下内容：
+ 页面 ID
+ 页面标题
+ 父页面 ID。– **只有应用程序监控启用 Cookie 时才会收集此信息。**
+ 交互深度 – **只有在应用程序监控启用 Cookie 时才会收集此信息。**
+ 页面标签 – 您可以向页面事件添加标签，将页面组合在一起。有关更多信息，请参阅 [使用页面组](CloudWatch-RUM-page-groups.md)。

### 用户代理元数据
<a name="CloudWatch-RUM-datacollected-metadata-useragent"></a>

用户代理元数据包括以下内容：
+ 浏览器语言
+ 浏览器名称
+ 浏览器版本
+ 操作系统名称
+ 操作系统版本
+ 设备类型
+ 平台类型

### 地理位置元数据
<a name="CloudWatch-RUM-datacollected-metadata-geolocation"></a>

地理位置元数据包括以下内容：
+ 国家/地区代码
+ 细分代码

### 域元数据
<a name="CloudWatch-RUM-datacollected-metadata-domain"></a>

域元数据包括 URL 域。

## RUM 事件详细信息
<a name="CloudWatch-RUM-datacollected-eventDetails"></a>

根据事件类型，事件的详细信息遵循以下类型的架构之一。

### 会话开启事件
<a name="CloudWatch-RUM-datacollected-sessionstart"></a>

此事件不包含字段。**只有应用程序监控启用 Cookie 时才会收集此信息。**

### 页面视图架构
<a name="CloudWatch-RUM-datacollected-pageview"></a>

**Page view**（页面视图）事件包含以下属性。您可以通过配置 Web 客户端来停用页面视图收集。有关更多信息，请参阅 [CloudWatch RUM Web 客户端文档](https://github.com/aws-observability/aws-rum-web/blob/main/docs/cdn_installation.md)。


| 名称 | Type | 说明 | 
| --- | --- | --- | 
|  **页面 ID** |  字符串  |  在应用程序中唯一代表此页面的 ID。默认情况下，这是 URL 路径。  | 
|  **父页面 ID** |  字符串  |  用户导航到当前页面时所在页面的 ID。**只有应用程序监控启用 Cookie 时才会收集此信息。**  | 
|  **交互深度** |  字符串  |  **只有应用程序监控启用 Cookie 时才会收集此信息。**  | 

### JavaScript 错误架构
<a name="CloudWatch-RUM-datacollected-JavaScriptError"></a>

代理生成的 JavaScript 错误事件包含以下属性。仅当您选择收集错误遥测时，Web 客户端才会收集这些事件。


| 名称 | Type | 说明 | 
| --- | --- | --- | 
|  **错误类型** |  字符串  |  错误名称（如果存在）。有关更多信息，请参阅 [Error.prototype.name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name)。 某些浏览器可能不支持错误类型。  | 
|  **错误消息** |  字符串  |  错误的消息。有关更多信息，请参阅 [Error.prototype.message](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message)。如果错误字段不存在，则这是错误事件消息。有关更多信息，请参阅 [ErroRevent](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent)。 不同浏览器之间的错误消息可能不一致。  | 
|  **堆栈跟踪** |  字符串  |  错误的堆栈跟踪（如果存在）将被截断为 150 个字符。有关更多信息，请参阅 [Error.prototype.stack](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack)。 某些浏览器可能不支持堆栈跟踪。  | 

### DOM 事件架构
<a name="CloudWatch-RUM-datacollected-DOMEvent"></a>

代理生成的文档对象模型 (DOM) 事件包含以下属性。默认情况下，不会收集这些事件。只有在激活交互遥测时才会收集。有关更多信息，请参阅 [CloudWatch RUM Web 客户端文档](https://github.com/aws-observability/aws-rum-web/blob/main/docs/cdn_installation.md)。


| 名称 | Type | 说明 | 
| --- | --- | --- | 
|  **Event (事件)** |  字符串  |  DOM 事件的类型，例如单击、滚动或悬停。有关更多信息，请参阅[事件参考](https://developer.mozilla.org/en-US/docs/Web/Events)。  | 
|  **元素** |  字符串  |  DOM 元素类型  | 
|  **元素 ID** |  字符串  |  如果生成事件的元素有 ID，则此属性存储该 ID。有关更多信息，请参阅 [Element.id](https://developer.mozilla.org/en-US/docs/Web/API/Element/id)。  | 
|  **CSSLocator** |  字符串  |  用于识别 DOM 元素的 CSS 定位器。  | 
|  **InteractionId** |  字符串  |  用户与 UI 之间交互的唯一 ID。  | 

### 导航事件架构
<a name="CloudWatch-RUM-datacollected-NavigationEvent"></a>

只有在应用程序监控激活性能遥测时，才会收集导航事件。

导航事件使用 [Navigation timing Level 1](https://www.w3.org/TR/navigation-timing/#performancetiming) 和 [Navigation timing Level 2](https://w3c.github.io/navigation-timing) API。并非所有浏览器都支持 Level 2 API，因此这些较新的字段是可选的。

**注意**  
时间戳指标基于 [DOMHighResTimestamp](https://www.w3.org/TR/hr-time-2/#sec-domhighrestimestamp)。使用 Level 2 API，默认情况下，所有时间都相对于 `startTime`。但是对于 Level 1，需从时间戳指标中减去 `navigationStart` 指标以获取相对值。所有时间戳值均以毫秒为单位。

导航事件包含以下属性。


| 名称 | Type | 说明 | 备注 | 
| --- | --- | --- | --- | 
|  **initiatorType** |  字符串  |  表示启动性能事件的资源类型。 |  **值：**“navigation” **Level 1：**“navigation” **Level 2：**entryData.initiatorType | 
|  **navigationType** |  字符串  |  表示导航类型。此属性非必需。 |  **值：**该值必须是以下之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-datacollected.html) | 
|  **startTime** |  数字  |  指示触发事件的时间。 |  **值：**0 **Level 1：**entryData.navigationStart - entryData.navigationStart  **Level 2：**entryData.startTime | 
|  **unloadEventStart** |  数字  |  指示引发 `unload` 事件后，窗口中上一个文档开始卸载的时间。 |  **值：**如果不存在上一个文档，或者上一个文档或者其中一个所需的重新导向不是同一来源，则返回值为 0。 **Level 1：** <pre>entryData.unloadEventStart > 0<br />  ? entryData.unloadEventStart - entryData.navigationStart<br />  : 0<br /></pre> **Level 2：**entryData.unloadEventStart | 
|  **promptForUnload** |  数字  |  卸载文档所用的时间。换言之，`unloadEventStart` 和 `unloadEventEnd` 之间的时间。`UnloadEventEnd` 表示卸载事件处理程序完成的时刻（以毫秒为单位）。 |  **值：**如果不存在上一个文档，或者上一个文档或者其中一个所需的重新导向不是同一来源，则返回值为 0。 **Level 1：**entryData.unloadEventEnd - entryData.unloadEventStart **Level 2：**entryData.unloadEventEnd - entryData.unloadEventStart | 
|  **redirectCount** |  数字  |  表示在当前浏览的上下文中自上次非重新导向导航以来的重新导向次数。 此属性非必需。 |  **值：**如果没有重新导向，或者如果有与目标文档不同源的任何重新导向，则返回值为 0。 **Level 1：**不可用 **Level 2：**entryData.redirectCount | 
|  **redirectStart** |  数字  |  第一次 HTTP 重新导向开始的时间。  |  **值：**如果没有重新导向，或者如果有与目标文档不同源的任何重新导向，则返回值为 0。 **Level 1：** <pre>entryData.redirectStart > 0<br />  ? entryData.redirectStart - entryData.navigationStart<br />  : 0</pre> **Level 2：**entryData.redirectStart | 
|  **redirectTime** |  数字  |  HTTP 重新导向所用的时间。这是 `redirectStart` 与 `redirectEnd` 之间的差异。  |  **Level 1：** : entryData.redirectEnd - entryData.redirectStart **Level 2：** : entryData.redirectEnd - entryData.redirectStart | 
|  **WorkerStart** |  数字  |  这是 `PerformanceResourceTiming` 接口的属性。这标志着工件线程操作开始。 此属性非必需。 |  **值：**如果 Service Worker 线程已运行，或紧靠启动 Service Worker 线程之前，则此属性将返回紧靠分派 `FetchEvent` 前的时间。如果 Service Worker 未拦截资源，则返回 0。 **Level 1：**不可用 **Level 2：**entryData.workerStart | 
|  **workerTime** |  数字  |  如果 Service Worker 未拦截资源，则返回工件线程操作所需的时间。 此属性非必需。 |  **Level 1：**不可用  **Level 2：**<pre>entryData.workerStart > 0<br />   ? entryData.fetchStart - entryData.workerStart<br />   : 0</pre>  | 
|  **fetchStart** |  数字  |  浏览器准备好使用 HTTP 请求获取文档的时间。这在检查任何应用程序缓存之前完成。 |  **Level 1：** <pre>: entryData.fetchStart > 0<br />  ? entryData.fetchStart - entryData.navigationStart<br />  : 0</pre> **Level 2：**entryData.fetchStart | 
|  **domainLookupStar** |  数字  |  域查找开始的时间。 |  **值：**如果使用持久连接或信息存储在缓存或本地资源中，则该值将与 `fetchStart` 相同。 **Level 1：** <pre>entryData.domainLookupStart > 0<br />  ? entryData.domainLookupStart - entryData.navigationStart<br />  : 0</pre> **Level 2：**entryData.domainLookupStart | 
|  **dns** |  数字  |  域名查找所需的时间。 |  **值：**如果缓存了资源和 DNS 记录，则预期值为 0。 **Level 1：**entryData.domainLookupEnd - entryData.domainLookupStart **Level 2：**entryData.domainLookupEnd - entryData.domainLookupStart | 
|  **nextHopProtocol** |  字符串  |  表示用于获取资源的网络协议的字符串。 此属性非必需。 |  **Level 1：**不可用 **Level 2：**entryData.nextHopProtocol | 
|  **connectStart** |  数字  |  紧靠用户代理开始建立与服务器的连接以检索文档之前的时间。 |  **值：**如果使用了 RFC2616 持久连接，或者如果从相关应用程序缓存或本地资源中检索当前文档，则此属性将返回 `domainLookupEnd` 值。 **Level 1：** <pre>entryData.connectStart > 0<br />  ? entryData.connectStart - entryData.navigationStart<br />  : 0</pre> **Level 2：**entryData.connectStart  | 
|  **connect** |  数字  |  评估建立传输连接或执行 SSL 身份验证所需的时间。其中还包括浏览器发出过多并发请求时所用的受阻时间。  |  **Level 1：**entryData.connectEnd - entryData.connectStart **Level 2：**entryData.connectEnd - entryData.connectStart | 
|  **secureConnectionStart** |  数字  |  如果当前页面的 URL 模式为“https”，则此属性将返回紧靠用户代理启动握手过程以保护当前连接之前的时间。如果未使用 HTTPS，则返回 0。有关 URL 模式的更多信息，请参阅 [URL 表示形式](https://url.spec.whatwg.org/#concept-url-scheme)。  |  **公式：**entryData.secureConnectionStart | 
|  **tlsTime** |  数字  |  完成 SSL 握手所需的时间。  |  **Level 1：** <pre>entryData.secureConnectionStart > 0<br />   ? entryData.connectEnd - entryData.secureConnectionStart<br />   : 0</pre> **Level 2：** <pre>entryData.secureConnectionStart > 0<br />   ? entryData.connectEnd - entryData.secureConnectionStart<br />   : 0</pre>  | 
|  **requestStart** |  数字  |  紧靠用户代理开始从服务器、相关应用程序缓存或本地资源请求资源之前的时间。  | **Level 1：** <pre>: entryData.requestStart > 0<br />  ? entryData.requestStart - entryData.navigationStart<br />  : 0<br /></pre> **Level 2：**entryData.requestStart | 
|  **timeToFirstByte** |  数字  |  发出请求后接收信息第一个字节所需的时间。此时间相对于 `startTime`。  | **Level 1：**entryData.responseStart - entryData.requestStart **Level 2：**entryData.responseStart - entryData.requestStart | 
|  **responseStart** |  数字  |  紧靠用户代理的 HTTP 解析器从相关应用程序缓存、本地资源或服务器接收响应的第一个字节之后的时间。  | **Level 1：** <pre>entryData.responseStart > 0<br />   ? entryData.responseStart - entryData.navigationStart<br />   : 0</pre> **Level 2：**entryData.responseStart   | 
|  **responseTime** |  字符串  |  以字节形式从相关应用程序缓存、本地资源或服务器接收完整响应所用的时间。  | **Level 1：** <pre>entryData.responseStart > 0<br />  ? entryData.responseEnd - entryData.responseStart<br />  : 0</pre> **Level 2：** <pre>entryData.responseStart > 0<br />  ? entryData.responseEnd - entryData.responseStart<br />  : 0</pre>  | 
|  **domInteractive** |  数字  |  解析器在主文档上完成工作以及构建 HTML DOM 所用的时间。此时，其 `Document.readyState` 变为“交互式”，并引发相应的 `readystatechange` 事件。  | **Level 1：** <pre>entryData.domInteractive > 0<br />  ? entryData.domInteractive - entryData.navigationStart<br />  : 0</pre> **Level 2：**entryData.domInteractive  | 
|  **domContentLoadedEventStart** |  数字  |  表示紧靠用户代理在当前文档中触发 DOMContentLoaded 事件之前的时间值。初始 HTML 文档完全加载和解析后，将触发 DOMContentLoaded 事件。此时，主 HTML 文档已完成解析，浏览器开始构建渲染树，并且还需要加载子资源。此步骤不会等待样式表、图像和子框架完成加载。  | **Level 1：** <pre>entryData.domContentLoadedEventStart > 0<br />  ? entryData.domContentLoadedEventStart - entryData.navigationStart<br />  : 0<br /></pre> **Level 2：**entryData.domContentLoadedEventStart  | 
|  **domContentLoaded** |  数字  |  渲染树构建的此开启时间和结束时间使用 `domContentLoadedEventStart` 和 `domContentLoadedEventEnd` 标记。其允许 CloudWatch RUM 跟踪执行情况。此属性是 `domContentLoadedStart` 与 `domContentLoadedEnd` 之间的差异。 在此期间，DOM 和 CSSOM 已准备就绪。此属性将等待脚本执行，但异步和动态创建的脚本除外。如果脚本依赖样式表，`domContentLoaded` 也将等待样式表。其不会等待图像。  在 Google Chrome 的网络面板中，`domContentLoadedStart` 和 `domContentLoadedEnd` 的实际值与 `domContentLoaded` 近似。这表示从页面加载过程开始的 HTML DOM \$1 CSSOM 渲染树构建时间。如果是导航指标，`domContentLoaded` 值表示开始和结束值之间的差异，这是仅下载子资源和渲染树构建所需的时间。   | **Level 2：**entryData.domContentLoadedEventEnd - entryData.domContentLoadedEventStart  **Level 2：**entryData.domContentLoadedEventEnd - entryData.domContentLoadedEventStart  | 
|  **domComplete** |  数字  |  紧靠浏览器将当前文档的当前文档准备就绪状态设置为完成之前的时间。此时，子资源（例如图像）的加载已经完成。这包括下载 CSS 和同步 JavaScript 等阻止内容所用的时间。在 Google Chrome 的网络面板中，此属性与 `loadTime` 近似。  | **Level 1：** <pre>entryData.domComplete > 0<br />  ? entryData.domComplete - entryData.navigationStart<br />  : 0<br /></pre> **Level 2：**entryData.domComplete  | 
|  **domProcessingTime** |  数字  |  响应和加载事件开始之间的总时间。  | **Level 1：**entryData.loadEventStart - entryData.responseEnd **Level 2：**entryData.loadEventStart - entryData.responseEnd  | 
|  **loadEventStart** |  数字  |  紧靠当前文档 `load` 事件触发之前的时间。 |  **Level 1：** <pre>entryData.loadEventStart > 0<br />  ? entryData.loadEventStart - entryData.navigationStart<br />  : 0<br /></pre> **Level 2：**entryData.loadEventStart | 
|  **loadEventTime** |  数字  |  `loadEventStart` 与 `loadEventEnd` 之间的差异。在此期间，将触发等待此加载事件的其他函数或逻辑。 |  **Level 1：**entryData.loadEventEnd - entryData.loadEventStart **Level 2：**entryData.loadEventEnd - entryData.loadEventStart | 
|  **duration** |  字符串  |  持续时间为页面总加载时间。其记录下载主页面及其所有同步子资源的时间，以及渲染页面的时间。稍后还会继续下载脚本等异步资源。此属性是 `loadEventEnd` 与 `startTime` 属性之间的差异。  | **Level 1：**entryData.loadEventEnd - entryData.navigationStart **Level 2：**entryData.duration | 
|  **headerSize** |  数字  |  返回 `transferSize` 与 `encodedBodySize` 之间的差异。 此属性非必需。  | **Level 1：**不可用 **Level 2：**entryData.transferSize - entryData.encodedBodySize **Level 2：**entryData.transferSize - entryData.encodedBodySize | 
|  **compressionRatio** |  数字  |  `encodedBodySize` 和 `decodedBodySize` 的比率。`encodedBodySize` 的值是不包括 HTTP 标头的资源的压缩大小。`decodedBodySize` 的值是不包括 HTTP 标头的资源的解压大小。 此属性非必需。  | **Level 1：**不可用。 **Level 2：**<pre>entryData.encodedBodySize > 0<br />  ? entryData.decodedBodySize / entryData.encodedBodySize<br />  : 0</pre>  | 
|  **navigationTimingLevel** |  数字  |  Navigation timing API 版本。  | **值：**1 或 2  | 

### 资源事件架构
<a name="CloudWatch-RUM-datacollected-ResourceEvent"></a>

只有在应用程序监控已激活性能遥测时，才会收集资源事件。

时间戳指标基于 [DOMHighResTimeStamp typedef](https://www.w3.org/TR/hr-time-2/#sec-domhighrestimestamp)。对于 Level 2 API，默认情况下，所有计时都相对于 `startTime`。但是对于 Level 1 API，需从时间戳指标中减去 `navigationStart` 指标以获取相对值。所有时间戳值均以毫秒为单位。

代理生成的资源事件包含以下属性。


| 名称 | Type | 说明 | 备注 | 
| --- | --- | --- | --- | 
|  **targetUrl** |  字符串  |  返回资源的 URL。 |  **公式：**[entryData.name](http://entrydata.name/) | 
|  **initiatorType** |  字符串  |  表示启动性能资源事件的资源类型。 |  **值：**"resource" **公式：**entryData.initiatorType | 
|  **duration** |  字符串  |  返回 `responseEnd` 与 `startTime` 属性之间的差异。此属性非必需。  | **公式：**entryData.duration | 
|  **transferSize** |  数字  |  返回获取的资源大小（八位字节），包括响应标头字段和响应有效负载正文。此属性非必需。  | **公式：**entryData.transferSize | 
|  **fileType** |  字符串  |  从目标 URL 模式派生的扩展。  |   | 

### 最大内容绘制事件架构
<a name="CloudWatch-RUM-datacollected-LargestPaintEvent"></a>

最大内容绘制事件包含以下属性。

只有在应用程序监控已激活性能遥测时，才会收集这些事件。


| 名称 | 描述 | 
| --- | --- | 
|  **值** |  有关更多信息，请参阅 [Web 重要信息](https://web.dev/vitals/)。 | 

### 首次输入延迟事件
<a name="CloudWatch-RUM-datacollected-FirstInputDelayEvent"></a>

首次输入延迟事件包含以下属性。

只有在应用程序监控已激活性能遥测时，才会收集这些事件。


| 名称 | 描述 | 
| --- | --- | 
|  **值** |  有关更多信息，请参阅 [Web 重要信息](https://web.dev/vitals/)。 | 

### 累计布局偏移事件
<a name="CloudWatch-RUM-datacollected-CumulativeShift"></a>

累计布局转移事件包含以下属性。

只有在应用程序监控已激活性能遥测时，才会收集这些事件。


| 名称 | 描述 | 
| --- | --- | 
|  **值** |  有关更多信息，请参阅 [Web 重要信息](https://web.dev/vitals/)。 | 

### HTTP 事件
<a name="CloudWatch-RUM-datacollected-HTTP"></a>

HTTP 事件包含以下属性。其中将包含 `Response` 字段或 `Error` 字段，但无法二者皆包含。

只有在应用程序监控已激活 HTTP 性能遥测时，才会收集这些事件。


| 名称 | 描述 | 
| --- | --- | 
|  **请求** |  请求字段包含以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-datacollected.html)  | 
|  **响应** |  响应字段包含以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-datacollected.html)  | 
|  **错误** |  错误字段包含以下内容： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM-datacollected.html)  | 

### X-Ray 跟踪事件架构
<a name="CloudWatch-RUM-datacollected-xraytraceEvent"></a>

只有在应用程序监控已激活 X-Ray 跟踪时，才会收集这些事件。

有关 X-Ray 跟踪事件架构的信息，请参阅 [AWS X-Ray 分段文档](https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html)。

# 单页应用程序的路由更改计时
<a name="CloudWatch-RUM-route-change-timing"></a>

在传统的多页面应用程序中，当用户请求加载新内容时，用户实际上是在向服务器请求新的 HTML 页面。因此，CloudWatch RUM Web 客户端使用常规性能 API 指标来捕获加载时间。

但是，单页 Web 应用程序使用 JavaScript 和 Ajax 来更新界面，而无需从服务器加载新页面。浏览器计时 API 不会记录单页更新，而是使用路由更改计时。

CloudWatch RUM 支持监控来自服务器的整页加载和单页更新，但有以下区别：
+ 对于路由更改计时，没有浏览器提供的指标，例如 `tlsTime`、`timeToFirstByte` 等等。
+ 对于路由更改计时，`initiatorType` 字段将为 `route_change`。

CloudWatch RUM Web 客户端监听可能导致路由变更的用户交互，当记录此类用户交互时，Web 客户端会记录一个时间戳。如果满足以下两个条件，则将开始路由更改计时：
+ 浏览器历史记录 API（浏览器前进和后退按钮除外）用于执行路由更改。
+ 路由更改检测时间与最新用户交互时间戳之间的差异小于 1000 ms。这样可以避免数据偏斜。

然后，一旦路由更改计时开始，如果没有正在进行的 AJAX 请求和 DOM 更改，则该计时结束。然后，最新完成的活动的时间戳将用作完成时间戳。

如果有持续的 AJAX 请求或 DOM 变更超过 10 秒（默认），则路由更改计时将超时。在这种情况下，CloudWatch RUM Web 客户端将不再记录此路由更改的计时。

因此，路由更改事件的持续时间按以下公式计算：

```
(time of latest completed activity) - (latest user interaction timestamp)
```