chrome-devtools-frontend 1.0.1516909 → 1.0.1518653

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.
Files changed (94) hide show
  1. package/docs/checklist/README.md +2 -2
  2. package/docs/checklist/javascript.md +1 -1
  3. package/docs/contributing/README.md +1 -1
  4. package/docs/contributing/settings-experiments-features.md +9 -8
  5. package/docs/cookbook/devtools_on_devtools.md +2 -2
  6. package/docs/cookbook/localization.md +10 -10
  7. package/docs/devtools-protocol.md +9 -8
  8. package/docs/ecosystem/automatic_workspace_folders.md +3 -3
  9. package/docs/get_the_code.md +0 -2
  10. package/docs/styleguide/ux/components.md +166 -85
  11. package/docs/styleguide/ux/numbers.md +3 -4
  12. package/front_end/core/common/README.md +13 -12
  13. package/front_end/core/host/GdpClient.ts +16 -1
  14. package/front_end/core/host/UserMetrics.ts +4 -2
  15. package/front_end/core/root/Runtime.ts +13 -0
  16. package/front_end/core/sdk/CSSMatchedStyles.ts +5 -1
  17. package/front_end/entrypoints/main/MainImpl.ts +6 -3
  18. package/front_end/generated/InspectorBackendCommands.js +10 -7
  19. package/front_end/generated/SupportedCSSProperties.js +21 -7
  20. package/front_end/generated/protocol-mapping.d.ts +16 -1
  21. package/front_end/generated/protocol-proxy-api.d.ts +13 -1
  22. package/front_end/generated/protocol.ts +95 -0
  23. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +166 -49
  24. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +14 -181
  25. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +13 -315
  26. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +224 -50
  27. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +310 -11
  28. package/front_end/models/ai_assistance/performance/AIContext.ts +15 -2
  29. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +17 -11
  30. package/front_end/models/badges/Badge.ts +8 -3
  31. package/front_end/models/badges/CodeWhispererBadge.ts +2 -4
  32. package/front_end/models/badges/StarterBadge.ts +2 -2
  33. package/front_end/models/badges/UserBadges.ts +21 -3
  34. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  35. package/front_end/models/trace/README.md +28 -1
  36. package/front_end/models/trace/handlers/UserTimingsHandler.ts +1 -1
  37. package/front_end/models/trace/helpers/Trace.ts +99 -43
  38. package/front_end/models/trace/types/TraceEvents.ts +9 -0
  39. package/front_end/panels/accessibility/ARIAAttributesView.ts +113 -191
  40. package/front_end/panels/accessibility/AccessibilityNodeView.ts +9 -9
  41. package/front_end/panels/accessibility/AccessibilitySubPane.ts +6 -4
  42. package/front_end/panels/accessibility/accessibilityProperties.css +2 -0
  43. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +16 -2
  44. package/front_end/panels/ai_assistance/components/ChatView.ts +9 -10
  45. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +42 -0
  46. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +32 -9
  47. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +7 -1
  48. package/front_end/panels/common/BadgeNotification.ts +21 -5
  49. package/front_end/panels/common/GdpSignUpDialog.ts +18 -9
  50. package/front_end/panels/console/ConsolePrompt.ts +1 -1
  51. package/front_end/panels/console/ConsoleView.ts +6 -2
  52. package/front_end/panels/elements/ElementsPanel.ts +4 -0
  53. package/front_end/panels/elements/ElementsTreeElement.ts +18 -0
  54. package/front_end/panels/elements/ElementsTreeOutline.ts +13 -0
  55. package/front_end/panels/elements/StylePropertyTreeElement.ts +21 -6
  56. package/front_end/panels/media/TickingFlameChart.ts +1 -1
  57. package/front_end/panels/profiler/HeapSnapshotView.ts +34 -19
  58. package/front_end/panels/search/SearchResultsPane.ts +124 -128
  59. package/front_end/panels/search/SearchView.ts +24 -17
  60. package/front_end/panels/settings/components/SyncSection.ts +16 -8
  61. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +6 -1
  62. package/front_end/panels/sources/SourcesPanel.ts +3 -0
  63. package/front_end/panels/timeline/AppenderUtils.ts +2 -2
  64. package/front_end/panels/timeline/ExtensionTrackAppender.ts +13 -4
  65. package/front_end/panels/timeline/GPUTrackAppender.ts +2 -1
  66. package/front_end/panels/timeline/InteractionsTrackAppender.ts +5 -1
  67. package/front_end/panels/timeline/LayoutShiftsTrackAppender.ts +2 -1
  68. package/front_end/panels/timeline/ThreadAppender.ts +12 -3
  69. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +9 -4
  70. package/front_end/panels/timeline/TimelinePanel.ts +3 -2
  71. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -4
  72. package/front_end/panels/timeline/TimingsTrackAppender.ts +6 -1
  73. package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +95 -82
  74. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
  75. package/front_end/panels/timeline/components/cpuThrottlingSelector.css +17 -15
  76. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +3 -0
  77. package/front_end/third_party/chromium/README.chromium +1 -1
  78. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  79. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  80. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +6 -9
  81. package/front_end/third_party/codemirror.next/package.json +2 -1
  82. package/front_end/third_party/diff/README.chromium +1 -0
  83. package/front_end/ui/components/text_editor/config.ts +6 -7
  84. package/front_end/ui/components/tooltips/Tooltip.ts +70 -31
  85. package/front_end/ui/legacy/README.md +33 -24
  86. package/front_end/ui/legacy/SearchableView.ts +19 -26
  87. package/front_end/ui/legacy/TextPrompt.ts +166 -1
  88. package/front_end/ui/legacy/Treeoutline.ts +16 -2
  89. package/front_end/ui/legacy/UIUtils.ts +15 -2
  90. package/front_end/ui/legacy/XElement.ts +0 -43
  91. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +20 -4
  92. package/front_end/ui/visual_logging/KnownContextValues.ts +19 -6
  93. package/front_end/ui/visual_logging/README.md +43 -27
  94. package/package.json +1 -1
@@ -5,11 +5,10 @@
5
5
  import * as Common from '../../../core/common/common.js';
6
6
  import * as Trace from '../../trace/trace.js';
7
7
  import type {ConversationSuggestions} from '../agents/AiAgent.js';
8
+ import type {AgentFocus} from '../performance/AIContext.js';
8
9
 
9
- import {
10
- NetworkRequestFormatter,
11
- } from './NetworkRequestFormatter.js';
12
- import {bytes, micros, millis} from './UnitFormatters.js';
10
+ import {PerformanceTraceFormatter} from './PerformanceTraceFormatter.js';
11
+ import {bytes, millis} from './UnitFormatters.js';
13
12
 
14
13
  /**
15
14
  * For a given frame ID and navigation ID, returns the LCP Event and the LCP Request, if the resource was an image.
@@ -40,13 +39,14 @@ function getLCPData(parsedTrace: Trace.TraceModel.ParsedTrace, frameId: string,
40
39
  };
41
40
  }
42
41
 
43
- export class PerformanceInsightFormatter {
42
+ export class PerformanceInsightFormatter extends PerformanceTraceFormatter {
44
43
  #insight: Trace.Insights.Types.InsightModel;
45
44
  #parsedTrace: Trace.TraceModel.ParsedTrace;
46
45
 
47
- constructor(parsedTrace: Trace.TraceModel.ParsedTrace, insight: Trace.Insights.Types.InsightModel) {
46
+ constructor(focus: AgentFocus, insight: Trace.Insights.Types.InsightModel) {
47
+ super(focus);
48
48
  this.#insight = insight;
49
- this.#parsedTrace = parsedTrace;
49
+ this.#parsedTrace = focus.data.parsedTrace;
50
50
  }
51
51
 
52
52
  #formatMilli(x?: number): string {
@@ -89,8 +89,8 @@ export class PerformanceInsightFormatter {
89
89
 
90
90
  if (lcpRequest) {
91
91
  parts.push(`${theLcpElement} is an image fetched from \`${lcpRequest.args.data.url}\`.`);
92
- const request = TraceEventFormatter.networkRequests(
93
- [lcpRequest], this.#parsedTrace, {verbose: true, customTitle: 'LCP resource network request'});
92
+ const request =
93
+ this.formatNetworkRequests([lcpRequest], {verbose: true, customTitle: 'LCP resource network request'});
94
94
  parts.push(request);
95
95
  } else {
96
96
  parts.push(`${theLcpElement} is text and was not fetched from the network.`);
@@ -266,7 +266,7 @@ ${shiftsFormatted.join('\n')}`;
266
266
 
267
267
  return `${this.#lcpMetricSharedContext()}
268
268
 
269
- ${TraceEventFormatter.networkRequests([documentRequest], this.#parsedTrace, {
269
+ ${this.formatNetworkRequests([documentRequest], {
270
270
  verbose: true,
271
271
  customTitle: 'Document network request'
272
272
  })}
@@ -592,8 +592,8 @@ ${filesFormatted}`;
592
592
  */
593
593
  formatModernHttpInsight(insight: Trace.Insights.Models.ModernHTTP.ModernHTTPInsightModel): string {
594
594
  const requestSummary = (insight.http1Requests.length === 1) ?
595
- TraceEventFormatter.networkRequests(insight.http1Requests, this.#parsedTrace, {verbose: true}) :
596
- TraceEventFormatter.networkRequests(insight.http1Requests, this.#parsedTrace);
595
+ this.formatNetworkRequests(insight.http1Requests, {verbose: true}) :
596
+ this.formatNetworkRequests(insight.http1Requests);
597
597
 
598
598
  if (requestSummary.length === 0) {
599
599
  return 'There are no requests that were served over a legacy HTTP protocol.';
@@ -690,7 +690,7 @@ ${requestSummary}`;
690
690
  * @returns a string formatted for sending to Ask AI.
691
691
  */
692
692
  formatRenderBlockingInsight(insight: Trace.Insights.Models.RenderBlocking.RenderBlockingInsightModel): string {
693
- const requestSummary = TraceEventFormatter.networkRequests(insight.renderBlockingRequests, this.#parsedTrace);
693
+ const requestSummary = this.formatNetworkRequests(insight.renderBlockingRequests);
694
694
 
695
695
  if (requestSummary.length === 0) {
696
696
  return 'There are no network requests that are render blocking.';
@@ -1060,11 +1060,6 @@ Polyfills and transforms enable older browsers to use new JavaScript features. H
1060
1060
  }
1061
1061
  }
1062
1062
 
1063
- export interface NetworkRequestFormatOptions {
1064
- verbose?: boolean;
1065
- customTitle?: string;
1066
- }
1067
-
1068
1063
  export class TraceEventFormatter {
1069
1064
  static layoutShift(
1070
1065
  shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.TraceModel.ParsedTrace,
@@ -1105,301 +1100,4 @@ export class TraceEventFormatter {
1105
1100
  - Score: ${shift.args.data?.weighted_score_delta.toFixed(4)}
1106
1101
  ${rootCauseText}`;
1107
1102
  }
1108
-
1109
- // Stringify network requests for the LLM model.
1110
- static networkRequests(
1111
- requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.TraceModel.ParsedTrace,
1112
- options?: NetworkRequestFormatOptions): string {
1113
- if (requests.length === 0) {
1114
- return '';
1115
- }
1116
-
1117
- let verbose;
1118
- if (options?.verbose !== undefined) {
1119
- verbose = options.verbose;
1120
- } else {
1121
- verbose = requests.length === 1;
1122
- }
1123
-
1124
- // Use verbose format for a single network request. With the compressed format, a format description
1125
- // needs to be provided, which is not worth sending if only one network request is being stringified.
1126
- // For a single request, use `formatRequestVerbosely`, which formats with all fields specified and does not require a
1127
- // format description.
1128
- if (verbose) {
1129
- return requests.map(request => this.#networkRequestVerbosely(request, parsedTrace, options?.customTitle))
1130
- .join('\n');
1131
- }
1132
-
1133
- return this.#networkRequestsArrayCompressed(requests, parsedTrace);
1134
- }
1135
-
1136
- /**
1137
- * This is the data passed to a network request when the Performance Insights
1138
- * agent is asking for information. It is a slimmed down version of the
1139
- * request's data to avoid using up too much of the context window.
1140
- * IMPORTANT: these set of fields have been reviewed by Chrome Privacy &
1141
- * Security; be careful about adding new data here. If you are in doubt please
1142
- * talk to jacktfranklin@.
1143
- */
1144
- static #networkRequestVerbosely(
1145
- request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
1146
- customTitle?: string): string {
1147
- const {
1148
- url,
1149
- statusCode,
1150
- initialPriority,
1151
- priority,
1152
- fromServiceWorker,
1153
- mimeType,
1154
- responseHeaders,
1155
- syntheticData,
1156
- protocol
1157
- } = request.args.data;
1158
-
1159
- const titlePrefix = `## ${customTitle ?? 'Network request'}`;
1160
-
1161
- // Note: unlike other agents, we do have the ability to include
1162
- // cross-origins, hence why we do not sanitize the URLs here.
1163
- const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
1164
- request,
1165
- request.args.data.frame,
1166
- parsedTrace.data.Meta.navigationsByFrameId,
1167
- );
1168
- const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
1169
-
1170
- // Gets all the timings for this request, relative to the base time.
1171
- // Note that this is the start time, not total time. E.g. "queuedAt: X"
1172
- // means that the request was queued at Xms, not that it queued for Xms.
1173
- const startTimesForLifecycle = {
1174
- queuedAt: request.ts - baseTime,
1175
- requestSentAt: syntheticData.sendStartTime - baseTime,
1176
- downloadCompletedAt: syntheticData.finishTime - baseTime,
1177
- processingCompletedAt: request.ts + request.dur - baseTime,
1178
- } as const;
1179
-
1180
- const mainThreadProcessingDuration =
1181
- startTimesForLifecycle.processingCompletedAt - startTimesForLifecycle.downloadCompletedAt;
1182
- const downloadTime = syntheticData.finishTime - syntheticData.downloadStart;
1183
-
1184
- const renderBlocking = Trace.Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(request);
1185
- const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(request);
1186
-
1187
- const priorityLines = [];
1188
- if (initialPriority === priority) {
1189
- priorityLines.push(`Priority: ${priority}`);
1190
- } else {
1191
- priorityLines.push(`Initial priority: ${initialPriority}`);
1192
- priorityLines.push(`Final priority: ${priority}`);
1193
- }
1194
-
1195
- const redirects = request.args.data.redirects.map((redirect, index) => {
1196
- const startTime = redirect.ts - baseTime;
1197
- return `#### Redirect ${index + 1}: ${redirect.url}
1198
- - Start time: ${micros(startTime)}
1199
- - Duration: ${micros(redirect.dur)}`;
1200
- });
1201
-
1202
- const initiators = this.#getInitiatorChain(parsedTrace, request);
1203
- const initiatorUrls = initiators.map(initiator => initiator.args.data.url);
1204
-
1205
- return `${titlePrefix}: ${url}
1206
- Timings:
1207
- - Queued at: ${micros(startTimesForLifecycle.queuedAt)}
1208
- - Request sent at: ${micros(startTimesForLifecycle.requestSentAt)}
1209
- - Download complete at: ${micros(startTimesForLifecycle.downloadCompletedAt)}
1210
- - Main thread processing completed at: ${micros(startTimesForLifecycle.processingCompletedAt)}
1211
- Durations:
1212
- - Download time: ${micros(downloadTime)}
1213
- - Main thread processing time: ${micros(mainThreadProcessingDuration)}
1214
- - Total duration: ${micros(request.dur)}${initiator ? `\nInitiator: ${initiator.args.data.url}` : ''}
1215
- Redirects:${redirects.length ? '\n' + redirects.join('\n') : ' no redirects'}
1216
- Status code: ${statusCode}
1217
- MIME Type: ${mimeType}
1218
- Protocol: ${protocol}
1219
- ${priorityLines.join('\n')}
1220
- Render blocking: ${renderBlocking ? 'Yes' : 'No'}
1221
- From a service worker: ${fromServiceWorker ? 'Yes' : 'No'}
1222
- Initiators (root request to the request that directly loaded this one): ${initiatorUrls.join(', ') || 'none'}
1223
- ${NetworkRequestFormatter.formatHeaders('Response headers', responseHeaders ?? [], true)}`;
1224
- }
1225
-
1226
- static #getOrAssignUrlIndex(urlIdToIndex: Map<string, number>, url: string): number {
1227
- let index = urlIdToIndex.get(url);
1228
- if (index !== undefined) {
1229
- return index;
1230
- }
1231
- index = urlIdToIndex.size;
1232
- urlIdToIndex.set(url, index);
1233
- return index;
1234
- }
1235
-
1236
- // A compact network requests format designed to save tokens when sending multiple network requests to the model.
1237
- // It creates a map that maps request URLs to IDs and references the IDs in the compressed format.
1238
- //
1239
- // Important: Do not use this method for stringifying a single network request. With this format, a format description
1240
- // needs to be provided, which is not worth sending if only one network request is being stringified.
1241
- // For a single request, use `formatRequestVerbosely`, which formats with all fields specified and does not require a
1242
- // format description.
1243
- static #networkRequestsArrayCompressed(
1244
- requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
1245
- parsedTrace: Trace.TraceModel.ParsedTrace): string {
1246
- const networkDataString = `
1247
- Network requests data:
1248
-
1249
- `;
1250
- const urlIdToIndex = new Map<string, number>();
1251
- const allRequestsText =
1252
- requests
1253
- .map(request => {
1254
- const urlIndex = TraceEventFormatter.#getOrAssignUrlIndex(urlIdToIndex, request.args.data.url);
1255
- return this.#networkRequestCompressedFormat(urlIndex, request, parsedTrace, urlIdToIndex);
1256
- })
1257
- .join('\n');
1258
-
1259
- const urlsMapString = 'allUrls = ' +
1260
- `[${
1261
- Array.from(urlIdToIndex.entries())
1262
- .map(([url, index]) => {
1263
- return `${index}: ${url}`;
1264
- })
1265
- .join(', ')}]`;
1266
-
1267
- return networkDataString + '\n\n' + urlsMapString + '\n\n' + allRequestsText;
1268
- }
1269
-
1270
- /**
1271
- * Network requests format description that is sent to the model as a fact.
1272
- */
1273
- static networkDataFormatDescription = `Network requests are formatted like this:
1274
- \`urlIndex;queuedTime;requestSentTime;downloadCompleteTime;processingCompleteTime;totalDuration;downloadDuration;mainThreadProcessingDuration;statusCode;mimeType;priority;initialPriority;finalPriority;renderBlocking;protocol;fromServiceWorker;initiators;redirects:[[redirectUrlIndex|startTime|duration]];responseHeaders:[header1Value|header2Value|...]\`
1275
-
1276
- - \`urlIndex\`: Numerical index for the request's URL, referencing the "All URLs" list.
1277
- Timings (all in milliseconds, relative to navigation start):
1278
- - \`queuedTime\`: When the request was queued.
1279
- - \`requestSentTime\`: When the request was sent.
1280
- - \`downloadCompleteTime\`: When the download completed.
1281
- - \`processingCompleteTime\`: When main thread processing finished.
1282
- Durations (all in milliseconds):
1283
- - \`totalDuration\`: Total time from the request being queued until its main thread processing completed.
1284
- - \`downloadDuration\`: Time spent actively downloading the resource.
1285
- - \`mainThreadProcessingDuration\`: Time spent on the main thread after the download completed.
1286
- - \`statusCode\`: The HTTP status code of the response (e.g., 200, 404).
1287
- - \`mimeType\`: The MIME type of the resource (e.g., "text/html", "application/javascript").
1288
- - \`priority\`: The final network request priority (e.g., "VeryHigh", "Low").
1289
- - \`initialPriority\`: The initial network request priority.
1290
- - \`finalPriority\`: The final network request priority (redundant if \`priority\` is always final, but kept for clarity if \`initialPriority\` and \`priority\` differ).
1291
- - \`renderBlocking\`: 't' if the request was render-blocking, 'f' otherwise.
1292
- - \`protocol\`: The network protocol used (e.g., "h2", "http/1.1").
1293
- - \`fromServiceWorker\`: 't' if the request was served from a service worker, 'f' otherwise.
1294
- - \`initiators\`: A list (separated by ,) of URL indices for the initiator chain of this request. Listed in order starting from the root request to the request that directly loaded this one. This represents the network dependencies necessary to load this request. If there is no initiator, this is empty.
1295
- - \`redirects\`: A comma-separated list of redirects, enclosed in square brackets. Each redirect is formatted as
1296
- \`[redirectUrlIndex|startTime|duration]\`, where: \`redirectUrlIndex\`: Numerical index for the redirect's URL. \`startTime\`: The start time of the redirect in milliseconds, relative to navigation start. \`duration\`: The duration of the redirect in milliseconds.
1297
- - \`responseHeaders\`: A list (separated by '|') of values for specific, pre-defined response headers, enclosed in square brackets.
1298
- The order of headers corresponds to an internal fixed list. If a header is not present, its value will be empty.
1299
- `;
1300
-
1301
- /**
1302
- *
1303
- * This is the network request data passed to the Performance agent.
1304
- *
1305
- * The `urlIdToIndex` Map is used to map URLs to numerical indices in order to not need to pass whole url every time it's mentioned.
1306
- * The map content is passed in the response together will all the requests data.
1307
- *
1308
- * See `networkDataFormatDescription` above for specifics.
1309
- */
1310
- static #networkRequestCompressedFormat(
1311
- urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.TraceModel.ParsedTrace,
1312
- urlIdToIndex: Map<string, number>): string {
1313
- const {
1314
- statusCode,
1315
- initialPriority,
1316
- priority,
1317
- fromServiceWorker,
1318
- mimeType,
1319
- responseHeaders,
1320
- syntheticData,
1321
- protocol,
1322
- } = request.args.data;
1323
-
1324
- const navigationForEvent = Trace.Helpers.Trace.getNavigationForTraceEvent(
1325
- request,
1326
- request.args.data.frame,
1327
- parsedTrace.data.Meta.navigationsByFrameId,
1328
- );
1329
- const baseTime = navigationForEvent?.ts ?? parsedTrace.data.Meta.traceBounds.min;
1330
- const queuedTime = micros(request.ts - baseTime);
1331
- const requestSentTime = micros(syntheticData.sendStartTime - baseTime);
1332
- const downloadCompleteTime = micros(syntheticData.finishTime - baseTime);
1333
- const processingCompleteTime = micros(request.ts + request.dur - baseTime);
1334
- const totalDuration = micros(request.dur);
1335
- const downloadDuration = micros(syntheticData.finishTime - syntheticData.downloadStart);
1336
- const mainThreadProcessingDuration = micros(request.ts + request.dur - syntheticData.finishTime);
1337
- const renderBlocking = Trace.Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(request) ? 't' : 'f';
1338
- const finalPriority = priority;
1339
- const headerValues = responseHeaders
1340
- ?.map(header => {
1341
- const value =
1342
- NetworkRequestFormatter.allowHeader(header.name) ? header.value : '<redacted>';
1343
- return `${header.name}: ${value}`;
1344
- })
1345
- .join('|');
1346
- const redirects = request.args.data.redirects
1347
- .map(redirect => {
1348
- const urlIndex = TraceEventFormatter.#getOrAssignUrlIndex(urlIdToIndex, redirect.url);
1349
- const redirectStartTime = micros(redirect.ts - baseTime);
1350
- const redirectDuration = micros(redirect.dur);
1351
- return `[${urlIndex}|${redirectStartTime}|${redirectDuration}]`;
1352
- })
1353
- .join(',');
1354
-
1355
- const initiators = this.#getInitiatorChain(parsedTrace, request);
1356
- const initiatorUrlIndices =
1357
- initiators.map(initiator => TraceEventFormatter.#getOrAssignUrlIndex(urlIdToIndex, initiator.args.data.url));
1358
-
1359
- const parts = [
1360
- urlIndex,
1361
- queuedTime,
1362
- requestSentTime,
1363
- downloadCompleteTime,
1364
- processingCompleteTime,
1365
- totalDuration,
1366
- downloadDuration,
1367
- mainThreadProcessingDuration,
1368
- statusCode,
1369
- mimeType,
1370
- priority,
1371
- initialPriority,
1372
- finalPriority,
1373
- renderBlocking,
1374
- protocol,
1375
- fromServiceWorker ? 't' : 'f',
1376
- initiatorUrlIndices.join(','),
1377
- `[${redirects}]`,
1378
- `[${headerValues ?? ''}]`,
1379
- ];
1380
- return parts.join(';');
1381
- }
1382
-
1383
- static #getInitiatorChain(
1384
- parsedTrace: Trace.TraceModel.ParsedTrace,
1385
- request: Trace.Types.Events.SyntheticNetworkRequest): Trace.Types.Events.SyntheticNetworkRequest[] {
1386
- const initiators: Trace.Types.Events.SyntheticNetworkRequest[] = [];
1387
-
1388
- let cur: Trace.Types.Events.SyntheticNetworkRequest|undefined = request;
1389
- while (cur) {
1390
- const initiator = parsedTrace.data.NetworkRequests.eventToInitiator.get(cur);
1391
- if (initiator) {
1392
- // Should never happen, but if it did that would be an infinite loop.
1393
- if (initiators.includes(initiator)) {
1394
- return [];
1395
- }
1396
-
1397
- initiators.unshift(initiator);
1398
- }
1399
-
1400
- cur = initiator;
1401
- }
1402
-
1403
- return initiators;
1404
- }
1405
1103
  }