@blueking/open-telemetry 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bk-rum.global.js +1 -1
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/index.js +201 -157
- package/dist/index.js.map +1 -1
- package/dist/plugins/resource.d.ts +11 -0
- package/dist/schema/attributes.d.ts +18 -0
- package/package.json +1 -1
- package/skills/bk-rum-otele/references/span-protocol.md +199 -14
|
@@ -2,13 +2,24 @@ import type { BkOTPlugin } from '../core/plugin';
|
|
|
2
2
|
/**
|
|
3
3
|
* Resource Timing 的统一消费端:静态资源按配置生成 span;Fetch/XHR timing 转交 request 插件,
|
|
4
4
|
* 与其已创建的请求 span 合并,避免同一次网络请求重复计数。
|
|
5
|
+
* worker 路由相关字段与 finalResponseHeadersStart 为浏览器已提供、但 TS lib.dom 尚未声明的 Resource Timing 字段。
|
|
5
6
|
*/
|
|
6
7
|
type ResourceTimingWithStatus = PerformanceResourceTiming & {
|
|
7
8
|
deliveryType?: string;
|
|
9
|
+
finalResponseHeadersStart?: number;
|
|
8
10
|
renderBlockingStatus?: string;
|
|
9
11
|
responseStatus?: number;
|
|
12
|
+
workerCacheLookupStart?: number;
|
|
13
|
+
workerFinalRouterSource?: string;
|
|
14
|
+
workerMatchedRouterSource?: string;
|
|
15
|
+
workerRouterEvaluationStart?: number;
|
|
10
16
|
};
|
|
11
17
|
export declare const getResourceTimingAttributes: (entry: ResourceTimingWithStatus) => Record<string, number>;
|
|
18
|
+
/**
|
|
19
|
+
* 原样上报 RT 时间点:数值保留 0(未发生或 TAO 不可见,消费端据此选瀑布图);
|
|
20
|
+
* 浏览器未提供(undefined)或空字符串不写入。
|
|
21
|
+
*/
|
|
22
|
+
export declare const getResourceTimingRawAttributes: (entry: ResourceTimingWithStatus) => Record<string, string | number>;
|
|
12
23
|
export declare const getResourceDuration: (entry: ResourceTimingWithStatus) => number;
|
|
13
24
|
export declare const getResourcePerformanceAttributes: (entry: ResourceTimingWithStatus) => {
|
|
14
25
|
'resource.size'?: number | undefined;
|
|
@@ -20,6 +20,24 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
20
20
|
readonly networkStatus: "network.status";
|
|
21
21
|
readonly nextHopProtocol: "resource.protocol";
|
|
22
22
|
readonly outcomeType: "outcome.type";
|
|
23
|
+
readonly resourceTimingConnectEnd: "resource.timing.connect_end";
|
|
24
|
+
readonly resourceTimingConnectStart: "resource.timing.connect_start";
|
|
25
|
+
readonly resourceTimingDomainLookupEnd: "resource.timing.domain_lookup_end";
|
|
26
|
+
readonly resourceTimingDomainLookupStart: "resource.timing.domain_lookup_start";
|
|
27
|
+
readonly resourceTimingFetchStart: "resource.timing.fetch_start";
|
|
28
|
+
readonly resourceTimingFinalResponseHeadersStart: "resource.timing.final_response_headers_start";
|
|
29
|
+
readonly resourceTimingRedirectEnd: "resource.timing.redirect_end";
|
|
30
|
+
readonly resourceTimingRedirectStart: "resource.timing.redirect_start";
|
|
31
|
+
readonly resourceTimingRequestStart: "resource.timing.request_start";
|
|
32
|
+
readonly resourceTimingResponseEnd: "resource.timing.response_end";
|
|
33
|
+
readonly resourceTimingResponseStart: "resource.timing.response_start";
|
|
34
|
+
readonly resourceTimingSecureConnectionStart: "resource.timing.secure_connection_start";
|
|
35
|
+
readonly resourceTimingStartTime: "resource.timing.start_time";
|
|
36
|
+
readonly resourceTimingWorkerCacheLookupStart: "resource.timing.worker_cache_lookup_start";
|
|
37
|
+
readonly resourceTimingWorkerFinalRouterSource: "resource.timing.worker_final_router_source";
|
|
38
|
+
readonly resourceTimingWorkerMatchedRouterSource: "resource.timing.worker_matched_router_source";
|
|
39
|
+
readonly resourceTimingWorkerRouterEvaluationStart: "resource.timing.worker_router_evaluation_start";
|
|
40
|
+
readonly resourceTimingWorkerStart: "resource.timing.worker_start";
|
|
23
41
|
readonly serviceName: "service.name";
|
|
24
42
|
readonly serviceVersion: "service.version";
|
|
25
43
|
readonly sessionHasReplay: "session.has_replay";
|
package/package.json
CHANGED
|
@@ -354,20 +354,38 @@ View B █████████████
|
|
|
354
354
|
| `attributes.resource.cache.hit` *[3]* |  | boolean | 缓存命中 | 命中时为 `true`,未命中或无法判断时不写入。 |
|
|
355
355
|
| `attributes.resource.delivery_type` *[4]* |  | str | 资源获取方式 | 浏览器返回非空值时存在。 |
|
|
356
356
|
| `attributes.resource.render_blocking_status` *[5]* |  | enum | 渲染阻塞状态 | 浏览器支持该字段时存在。 |
|
|
357
|
-
| `attributes.resource.redirect.start` |  | number | 重定向开始时间 | 可由 `redirectStart - startTime` 得到。 |
|
|
358
|
+
| `attributes.resource.redirect.duration` |  | number | 重定向耗时 | 可由 `redirectEnd - redirectStart` 得到。 |
|
|
359
|
+
| `attributes.resource.worker.start` |  | number | Service Worker 开始时间 | 可由 `workerStart - startTime` 得到。 |
|
|
360
|
+
| `attributes.resource.worker.duration` |  | number | Service Worker 耗时 | 可由 `fetchStart - workerStart` 得到。 |
|
|
361
|
+
| `attributes.resource.dns.start` |  | number | DNS 解析开始时间 | 可由 `domainLookupStart - startTime` 得到。 |
|
|
362
|
+
| `attributes.resource.dns.duration` |  | number | DNS 解析耗时 | 可由 `domainLookupEnd - domainLookupStart` 得到。 |
|
|
363
|
+
| `attributes.resource.connect.start` |  | number | 连接开始时间 | 可由 `connectStart - startTime` 得到。 |
|
|
364
|
+
| `attributes.resource.connect.duration` |  | number | 连接耗时(含 TLS) | 可由 `connectEnd - connectStart` 得到。 |
|
|
365
|
+
| `attributes.resource.ssl.start` |  | number | TLS 握手开始时间 | 可由 `secureConnectionStart - startTime` 得到。 |
|
|
366
|
+
| `attributes.resource.ssl.duration` |  | number | TLS 握手耗时 | 可由 `connectEnd - secureConnectionStart` 得到。 |
|
|
367
|
+
| `attributes.resource.first_byte.start` |  | number | 首字节等待开始时间 | 可由 `requestStart - startTime` 得到。 |
|
|
368
|
+
| `attributes.resource.first_byte.duration` |  | number | 首字节等待耗时 | 可由 `responseStart - requestStart` 得到。 |
|
|
369
|
+
| `attributes.resource.download.start` |  | number | 内容下载开始时间 | 可由 `responseStart - startTime` 得到。 |
|
|
370
|
+
| `attributes.resource.download.duration` |  | number | 内容下载耗时 | 可由 `responseEnd - responseStart` 得到。 |
|
|
371
|
+
| `attributes.resource.timing.start_time` |  | number | 资源开始时间 | 与 `responseEnd` 计算总耗时;也是阶段偏移基准。 |
|
|
372
|
+
| `attributes.resource.timing.redirect_start` |  | number | 重定向开始时间 | 与 `redirectEnd` 计算可见重定向链耗时。 |
|
|
373
|
+
| `attributes.resource.timing.redirect_end` |  | number | 重定向结束时间 | -- |
|
|
374
|
+
| `attributes.resource.timing.fetch_start` |  | number | 最后一跳获取开始时间 | 划分重定向后的前置等待。 |
|
|
375
|
+
| `attributes.resource.timing.worker_start` |  | number | Service Worker 介入时间 | 标记 Service Worker 参与,不代表实际执行耗时。 |
|
|
376
|
+
| `attributes.resource.timing.worker_router_evaluation_start` |  | number | Service Worker 路由评估时间 | 标记静态路由评估。 |
|
|
377
|
+
| `attributes.resource.timing.worker_cache_lookup_start` |  | number | Service Worker 缓存查询时间 | 标记缓存查询,不代表命中。 |
|
|
378
|
+
| `attributes.resource.timing.domain_lookup_start` |  | number | DNS 查询开始时间 | 与 `domainLookupEnd` 计算 DNS 耗时。 |
|
|
379
|
+
| `attributes.resource.timing.domain_lookup_end` |  | number | DNS 查询结束时间 | -- |
|
|
380
|
+
| `attributes.resource.timing.connect_start` |  | number | 连接开始时间 | 与 `connectEnd` 计算连接耗时(含 TLS)。 |
|
|
381
|
+
| `attributes.resource.timing.secure_connection_start` |  | number | TLS 开始时间 | 与 `connectEnd` 计算 TLS 耗时。 |
|
|
382
|
+
| `attributes.resource.timing.connect_end` |  | number | 连接完成时间 | -- |
|
|
383
|
+
| `attributes.resource.timing.request_start` |  | number | 请求开始时间 | 与 `responseStart` 计算等待首个响应的耗时。 |
|
|
384
|
+
| `attributes.resource.timing.response_start` |  | number | 首个响应时间 | 早于 `finalResponseHeadersStart` 时可识别 1xx;相等或最终响应头缺失,不能排除 1xx。 |
|
|
385
|
+
| `attributes.resource.timing.final_response_headers_start` |  | number | 最终响应头时间 | 与 `responseEnd` 计算最终响应交付耗时。 |
|
|
386
|
+
| `attributes.resource.timing.response_end` |  | number | 响应结束时间 | -- |
|
|
387
|
+
| `attributes.resource.timing.worker_matched_router_source` |  | str | Service Worker 命中来源 | 用于区分路由命中路径,可能不是最终来源。 |
|
|
388
|
+
| `attributes.resource.timing.worker_final_router_source` |  | str | Service Worker 最终来源 | 用于确定最终交付路径。 |
|
|
371
389
|
|
|
372
390
|
**[1] `attributes.resource.type`**:
|
|
373
391
|
|
|
@@ -575,3 +593,170 @@ SDK 原样上报浏览器返回的非空值,空值不写入。
|
|
|
575
593
|
### n. custom
|
|
576
594
|
|
|
577
595
|
`reportCustomEvent()` 产生 `custom.<name>` Span。`reportAction({ name })` 产生以 `action.name` 命名的 Span,且 `action.type=custom`。
|
|
596
|
+
|
|
597
|
+
## 0x04 资源加载时序
|
|
598
|
+
|
|
599
|
+
### a. W3C Resource Timing
|
|
600
|
+
|
|
601
|
+
字段定义见 [PerformanceResourceTiming](https://www.w3.org/TR/resource-timing/#the-performanceresourcetiming-interface)。下表按生命周期排序。
|
|
602
|
+
|
|
603
|
+
| 字段 | 含义 | attribute |
|
|
604
|
+
| --- | --- | --- |
|
|
605
|
+
| `startTime` | 这次取资源开始 | `attributes.resource.timing.start_time` |
|
|
606
|
+
| `redirectStart` | 第一次重定向开始 | `attributes.resource.timing.redirect_start` |
|
|
607
|
+
| `redirectEnd` | 最后一次重定向的响应收完 | `attributes.resource.timing.redirect_end` |
|
|
608
|
+
| `workerStart` | Service Worker 开始处理这次请求;未拦截时为 `0` | `attributes.resource.timing.worker_start` |
|
|
609
|
+
| `workerRouterEvaluationStart` | Service Worker 静态路由开始评估 | `attributes.resource.timing.worker_router_evaluation_start` |
|
|
610
|
+
| `workerCacheLookupStart` | Service Worker 静态路由开始查 Cache Storage,不代表命中 | `attributes.resource.timing.worker_cache_lookup_start` |
|
|
611
|
+
| `fetchStart` | 重定向结束后,开始取最终资源 | `attributes.resource.timing.fetch_start` |
|
|
612
|
+
| `domainLookupStart` | DNS 查询开始 | `attributes.resource.timing.domain_lookup_start` |
|
|
613
|
+
| `domainLookupEnd` | DNS 查询结束 | `attributes.resource.timing.domain_lookup_end` |
|
|
614
|
+
| `connectStart` | 开始建立到服务器的连接 | `attributes.resource.timing.connect_start` |
|
|
615
|
+
| `secureConnectionStart` | 可见 TLS 握手开始时间;复用连接时也可能被钳到 `fetchStart`,不能单凭非零值判断本次发生握手 | `attributes.resource.timing.secure_connection_start` |
|
|
616
|
+
| `connectEnd` | 连接建立完成,TLS 包含在内 | `attributes.resource.timing.connect_end` |
|
|
617
|
+
| `requestStart` | 开始向服务器发请求 | `attributes.resource.timing.request_start` |
|
|
618
|
+
| `firstInterimResponseStart` | 中间响应,例如 `103` | — |
|
|
619
|
+
| `responseStart` | 首个响应开始;存在 1xx 时指向首个临时响应,否则指向最终响应头 | `attributes.resource.timing.response_start` |
|
|
620
|
+
| `finalResponseHeadersStart` | 最终响应头开始;不保证浏览器均支持 | `attributes.resource.timing.final_response_headers_start` |
|
|
621
|
+
| `responseEnd` | 最后一字节到达,或连接先关闭 | `attributes.resource.timing.response_end` |
|
|
622
|
+
| `duration` | 总耗时,`responseEnd − startTime` | — |
|
|
623
|
+
| `name` | 资源 URL | `attributes.url.full` |
|
|
624
|
+
| `entryType` | 性能条目类型,固定为 `resource` | — |
|
|
625
|
+
| `initiatorType` | 发起方式,如 `script`、`link`、`img`、`fetch` | `attributes.resource.type` |
|
|
626
|
+
| `navigationId` | 所属页面导航的 ID | — |
|
|
627
|
+
| `nextHopProtocol` | 网络协议,如 `h2`、`h3` | `attributes.resource.protocol` |
|
|
628
|
+
| `deliveryType` | 资源获取方式,如 `cache`、`navigational-prefetch` | `attributes.resource.delivery_type` |
|
|
629
|
+
| `responseStatus` | HTTP 状态码 | `attributes.http.response.status_code` |
|
|
630
|
+
| `contentType` | 响应内容类型 | — |
|
|
631
|
+
| `contentEncoding` | 响应内容编码,如 `gzip`、`br` | — |
|
|
632
|
+
| `transferSize` | 规范化传输大小;本地缓存为 `0`,不是精确网络流量 | `attributes.resource.transfer_size` |
|
|
633
|
+
| `encodedBodySize` | 压缩后正文大小 | `attributes.resource.encoded_body_size` |
|
|
634
|
+
| `decodedBodySize` | 解码/解压后正文大小 | `attributes.resource.decoded_body_size` |
|
|
635
|
+
| `renderBlockingStatus` | 渲染阻塞状态 | `attributes.resource.render_blocking_status` |
|
|
636
|
+
| `serverTiming` | 服务端返回的 Server-Timing 指标 | — |
|
|
637
|
+
| `workerMatchedSourceType` | Service Worker 静态路由命中的来源 | `attributes.resource.timing.worker_matched_router_source` |
|
|
638
|
+
| `workerFinalSourceType` | Service Worker 最终使用的来源 | `attributes.resource.timing.worker_final_router_source` |
|
|
639
|
+
|
|
640
|
+
### b. 阶段划分
|
|
641
|
+
|
|
642
|
+
下表使用 `attributes.resource.timing` 上报字段计算阶段。绘图时,阶段时间点无效、顺序异常或计算耗时小于等于 `0`,均不画阶段条。
|
|
643
|
+
|
|
644
|
+
| 阶段 | 计算 | 术语介绍 | 用户感受 | 官方定义 |
|
|
645
|
+
| --- | --- | --- | --- | --- |
|
|
646
|
+
| 重定向 | `attributes.resource.timing.redirect_end − attributes.resource.timing.redirect_start` | 服务器返回 3xx 和新地址后,浏览器立即请求新地址,可能经过多次跳转,每次都多一次往返。 | 浏览器正在按服务器给出的新地址重新请求。 | W3C:[redirectStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-redirectstart)、[redirectEnd](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-redirectend) |
|
|
647
|
+
| 发起前等待 | C|D|E 类(无重定向):`attributes.resource.timing.fetch_start − attributes.resource.timing.start_time`<br />D|E 类(有重定向):`attributes.resource.timing.fetch_start − attributes.resource.timing.redirect_end` | 浏览器开始获取资源前的准备时间。 | 浏览器正在准备获取资源。 | W3C:[fetchStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-fetchstart) |
|
|
648
|
+
| [资源调度] 正在排队 | B 类:`attributes.resource.timing.worker_start − attributes.resource.timing.start_time` | 请求在连接开始前被排入队列,原因可能是有更高优先级的请求,或者同一来源的连接数已满。 | 浏览器正在排队,等待处理这次请求。 | W3C:[workerStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-workerstart);DevTools:`[资源调度] 正在排队` |
|
|
649
|
+
| [ServiceWorker] 启动 | `attributes.resource.timing.fetch_start − attributes.resource.timing.worker_start` | 浏览器启动 Service Worker,以便由它处理这次请求。 | 浏览器正在启动 Service Worker。 | W3C:[workerStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-workerstart);DevTools:[ServiceWorker] 启动 |
|
|
650
|
+
| [ServiceWorker] 向 ServiceWorker 发送的请求 | `attributes.resource.timing.request_start − attributes.resource.timing.fetch_start` | 浏览器把请求发送给 Service Worker 处理。 | 浏览器正在把请求发送给 Service Worker。 | W3C:[requestStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-requeststart);DevTools:`[ServiceWorker] 向 ServiceWorker 发送的请求` |
|
|
651
|
+
| [ServiceWorker] respondWith | 有首字节时间:`attributes.resource.timing.response_start − attributes.resource.timing.request_start`<br />无首字节时间:`attributes.resource.timing.response_end − attributes.resource.timing.request_start`<br />`attributes.resource.timing.request_start = 0` 时,起点改用 `attributes.resource.timing.fetch_start` | Service Worker 拦截请求后自行提供响应,例如读缓存或访问网络。 | Service Worker 正在处理请求,浏览器在等它交回响应。 | W3C:[Service Worker `respondWith`](https://w3c.github.io/ServiceWorker/#fetch-event-respondwith);DevTools:`[ServiceWorker] respondWith` |
|
|
652
|
+
| DNS | `attributes.resource.timing.domain_lookup_end − attributes.resource.timing.domain_lookup_start` | 浏览器通过 DNS 把资源域名解析为 IP 地址。 | 浏览器正在解析请求的 IP 地址。 | W3C:[domainLookupStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-domainlookupstart)、[domainLookupEnd](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-domainlookupend) |
|
|
653
|
+
| 连接建立 | 有 TLS:`attributes.resource.timing.secure_connection_start − attributes.resource.timing.connect_start`<br />无 TLS:`attributes.resource.timing.connect_end − attributes.resource.timing.connect_start` | 浏览器通过 TCP 握手与服务器建立连接。 | 浏览器正在和服务器建立连接。 | W3C:[connectStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-connectstart)、[connectEnd](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-connectend) |
|
|
654
|
+
| TLS | `attributes.resource.timing.connect_end − attributes.resource.timing.secure_connection_start` | 浏览器与服务器协商加密方式并验证服务器身份,建立安全连接。 | 浏览器正在和服务器确认身份、协商加密。 | W3C:[secureConnectionStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-secureconnectionstart);Fetch:[复用连接的时间点钳制](https://fetch.spec.whatwg.org/#clamp-and-coarsen-connection-timing-info) |
|
|
655
|
+
| 等待首字节 | D|E 类:`attributes.resource.timing.response_start − attributes.resource.timing.connect_end`<br />B 类:`attributes.resource.timing.response_start − attributes.resource.timing.request_start`(`attributes.resource.timing.request_start = 0` 时改用 `attributes.resource.timing.fetch_start`)<br />C 类:`attributes.resource.timing.response_start − attributes.resource.timing.fetch_start` | 浏览器发出请求后,等待服务器准备并返回响应第一个字节的时间。 | 浏览器正在发送请求并等待服务器回应。 | W3C:[requestStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-requeststart)、[responseStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-responsestart) |
|
|
656
|
+
| 内容下载 | 有首字节时间:`attributes.resource.timing.response_end − attributes.resource.timing.response_start`<br />B|C 类无首字节时间:`attributes.resource.timing.response_end − attributes.resource.timing.fetch_start` | 浏览器接收响应内容,从第一个字节到最后一个字节。 | 浏览器正在接收响应内容。 | W3C:[responseStart](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-responsestart)、[responseEnd](https://www.w3.org/TR/resource-timing/#dom-performanceresourcetiming-responseend) |
|
|
657
|
+
| 总耗时 | `attributes.resource.timing.response_end − attributes.resource.timing.start_time` | 从请求开始到收到响应最后一个字节的总时长。 | 从这次请求开始,到浏览器收完全部内容为止。 | W3C:[Timing-Allow-Origin](https://www.w3.org/TR/resource-timing/#sec-timing-allow-origin) |
|
|
658
|
+
|
|
659
|
+
### c. 瀑布图
|
|
660
|
+
|
|
661
|
+
按 A→E 顺序匹配;所有瀑布图在基础图上进一步修改,标为「可选」的阶段按图下表格的显示条件绘制。
|
|
662
|
+
|
|
663
|
+
| 瀑布图类型 | 说明 | 判断条件 | 备注 |
|
|
664
|
+
| --- | --- | --- | --- |
|
|
665
|
+
| A. 跨域明细不可见 | 只能展示总耗时 | 以下条件同时满足:<br />[1] `attributes.resource.timing.request_start = 0`;<br />[2] `attributes.resource.timing.response_start = 0`;<br />[3] `attributes.resource.decoded_body_size = 0` | -- |
|
|
666
|
+
| B. Service Worker 响应 | 主请求由 SW 的 `fetch` 事件交回响应 | 以下条件同时满足:<br />[1] `attributes.resource.timing.worker_start > 0`;<br />[2] 以下条件满足任一:<br />[a] `attributes.resource.timing.connect_end = 0`<br />[b] `attributes.resource.timing.connect_end = attributes.resource.timing.fetch_start`<br />[3] 以下条件满足任一:<br />[a] `attributes.resource.timing.worker_matched_router_source = null`<br />[b] `attributes.resource.timing.worker_matched_router_source = fetch-event`<br />[4] `attributes.resource.timing.worker_final_router_source ≠ cache` | SW 转发网络时主请求也看不到 DNS、建连,真实网络耗时在 SW 内部请求上,所以不归 D / E。 |
|
|
667
|
+
| C. 非网络响应 | 主请求没有可见的 DNS、建连和 TLS 阶段 | 以下条件同时满足:<br />[1] 以下条件满足任一:<br />[a] `attributes.resource.timing.connect_end = 0`<br />[b] `attributes.resource.timing.connect_end = attributes.resource.timing.fetch_start`<br />[2] 以下条件满足任一:<br />[a] `attributes.resource.delivery_type = cache && attributes.resource.transfer_size = 0`(浏览器缓存命中)<br />[b] `attributes.resource.delivery_type = null && attributes.resource.transfer_size = 0 && attributes.resource.decoded_body_size > 0`(推断缓存命中)<br />[c] `attributes.resource.timing.worker_final_router_source = cache`(Service Worker 静态路由命中缓存) | [2][b] 用于未上报 `delivery_type` 的浏览器:没有传输字节但有正文,按缓存命中处理。 |
|
|
668
|
+
| D. 连接复用 | DNS、建连耗时为 `0` ms | 以下条件同时满足:<br />[1] `attributes.resource.timing.domain_lookup_start = attributes.resource.timing.domain_lookup_end = attributes.resource.timing.connect_start = attributes.resource.timing.connect_end`;<br />[2] `attributes.resource.timing.connect_end ≠ 0` | -- |
|
|
669
|
+
| E. 网络请求 | 普通请求、缓存重新验证等 | 以下条件同时满足:<br />[1] 未匹配 A、B、C、D 类;<br />[2] `attributes.resource.timing.connect_start > 0 && attributes.resource.timing.connect_end > 0` | -- |
|
|
670
|
+
|
|
671
|
+
图例:`=` 阶段条,`-` 浅色条,`·` 分隔线。
|
|
672
|
+
|
|
673
|
+
#### A. 明细不可见
|
|
674
|
+
|
|
675
|
+
**基础图**
|
|
676
|
+
|
|
677
|
+
```text
|
|
678
|
+
startTime responseEnd
|
|
679
|
+
------------------------------------------------ 总耗时
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
#### B. Service Worker 响应
|
|
683
|
+
|
|
684
|
+
**基础图**
|
|
685
|
+
|
|
686
|
+
```text
|
|
687
|
+
startTime responseEnd
|
|
688
|
+
==== [资源调度] 正在排队
|
|
689
|
+
==== [ServiceWorker] 启动
|
|
690
|
+
= [ServiceWorker] 向 ServiceWorker 发送的请求(可选)
|
|
691
|
+
================= [ServiceWorker] respondWith
|
|
692
|
+
================= 等待首字节(可选)
|
|
693
|
+
====================== 内容下载
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
| 显示条件 | 阶段 | 说明 |
|
|
697
|
+
| --- | --- | --- |
|
|
698
|
+
| `requestStart > fetchStart` | [ServiceWorker] 向 ServiceWorker 发送的请求 | 通常为 `0` |
|
|
699
|
+
| `responseStart > 0` | 等待首字节 | 与 [ServiceWorker] respondWith 同起止。 |
|
|
700
|
+
|
|
701
|
+
> `responseStart = 0` (部分浏览器在 ServiceWorker 场景下,不记录 responseStart):「内容下载」改用 fetchStart -> responseEnd。
|
|
702
|
+
|
|
703
|
+
#### C. 非网络响应
|
|
704
|
+
|
|
705
|
+
**基础图**
|
|
706
|
+
|
|
707
|
+
```text
|
|
708
|
+
startTime responseEnd
|
|
709
|
+
======== 发起前等待
|
|
710
|
+
============ 等待首字节
|
|
711
|
+
============================ 内容下载
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
#### D. 连接复用
|
|
715
|
+
|
|
716
|
+
**基础图**
|
|
717
|
+
|
|
718
|
+
```text
|
|
719
|
+
startTime responseEnd
|
|
720
|
+
====== 重定向(可选)
|
|
721
|
+
==== 发起前等待
|
|
722
|
+
········ 连接复用:DNS、连接建立、TLS ········
|
|
723
|
+
==================== 等待首字节
|
|
724
|
+
================== 内容下载
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
> 为区分缓存场景,连接复用场景需要展示 DNS、建立连接、TLS 阶段
|
|
728
|
+
|
|
729
|
+
| 显示条件 | 阶段 | 说明 |
|
|
730
|
+
| --- | --- | --- |
|
|
731
|
+
| `redirectStart > 0` | 重定向 | 该请求经历重定向,最终一跳复用已有连接。 |
|
|
732
|
+
|
|
733
|
+
#### E. 网络请求
|
|
734
|
+
|
|
735
|
+
**基础图**
|
|
736
|
+
|
|
737
|
+
```text
|
|
738
|
+
startTime responseEnd
|
|
739
|
+
====== 重定向(可选)
|
|
740
|
+
=== 发起前等待
|
|
741
|
+
===== DNS(可选)
|
|
742
|
+
==== 连接建立(可选)
|
|
743
|
+
==== TLS(可选)
|
|
744
|
+
============ 等待首字节
|
|
745
|
+
============== 内容下载
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
| 显示条件 | 阶段 | 说明 |
|
|
749
|
+
| --- | --- | --- |
|
|
750
|
+
| `redirectStart > 0` | 重定向 | 最终请求前发生可见重定向时展示。 |
|
|
751
|
+
| `domainLookupStart > 0` | DNS | DNS 使用缓存或复用现有解析结果时。 |
|
|
752
|
+
| `connectStart > 0` | 连接建立 | 有 TLS 时计算到 `secureConnectionStart`;两者相等时没有独立的连接建立条。 |
|
|
753
|
+
| `secureConnectionStart > 0` | TLS | 只有 `connectEnd − secureConnectionStart` 为正且时间点有效时才绘制;非零时间点本身不代表有握手阶段。 |
|
|
754
|
+
|
|
755
|
+
### d. 后续扩展
|
|
756
|
+
|
|
757
|
+
当前版本暂不展示,后续可按需补充:
|
|
758
|
+
|
|
759
|
+
| 扩展 | 计算 | 生效条件 | 说明 |
|
|
760
|
+
| --- | --- | --- | --- |
|
|
761
|
+
| 临时响应 | `finalResponseHeadersStart − responseStart` | `firstInterimResponseStart > 0 && finalResponseHeadersStart > 0` | 服务器先回 `103` 等临时响应时,`responseStart` 指向首个临时响应,所以内容下载可拆成「临时响应」和「最终内容下载」两段。 |
|
|
762
|
+
| 最终内容下载 | `responseEnd − finalResponseHeadersStart` | 同上 | 从最终响应头到收完最后一个字节。|
|