RPP: show initiators for non-script network requests The logic to use the stack trace works for requests that have a stack trace, but for other requests we can still try to match based on the URL and show something to the user. Especially as they see the arrow in the flame chart, it's confusing if they then don't see anything in the details. Fixed: 363242792 Change-Id: I0a637ed730b0f34e732d929a5c757799bf130e11 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5839868 Auto-Submit: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Nancy Li <nancyly@chromium.org> Commit-Queue: Nancy Li <nancyly@chromium.org>
diff --git a/front_end/models/trace/helpers/Trace.ts b/front_end/models/trace/helpers/Trace.ts index 25578a8..36d8086 100644 --- a/front_end/models/trace/helpers/Trace.ts +++ b/front_end/models/trace/helpers/Trace.ts
@@ -25,7 +25,8 @@ * one based this function can yield unexpected results when used * indiscriminately. */ -function stackTraceForEvent(event: Types.TraceEvents.TraceEventData): Types.TraceEvents.TraceEventCallFrame[]|null { +export function stackTraceForEvent(event: Types.TraceEvents.TraceEventData): Types.TraceEvents.TraceEventCallFrame[]| + null { if (event.args?.data?.stackTrace) { return event.args.data.stackTrace; }
diff --git a/front_end/panels/timeline/TimelineDetailsView.test.ts b/front_end/panels/timeline/TimelineDetailsView.test.ts index 133b9cc..562ce78 100644 --- a/front_end/panels/timeline/TimelineDetailsView.test.ts +++ b/front_end/panels/timeline/TimelineDetailsView.test.ts
@@ -71,6 +71,10 @@ {title: 'Mime Type', value: 'text/css'}, {title: 'Encoded Data', value: ' (from cache)'}, {title: 'Decoded Body', value: '96 B'}, + { + title: 'Initiated by', + value: 'chromedevtools.github.io/performance-stories/lcp-web-font/index.html', + }, {title: 'From cache', value: 'Yes'}, {title: 'Duration', value: durationInnerText}, ],
diff --git a/front_end/panels/timeline/TimelineDetailsView.ts b/front_end/panels/timeline/TimelineDetailsView.ts index f10db85..a7ee267 100644 --- a/front_end/panels/timeline/TimelineDetailsView.ts +++ b/front_end/panels/timeline/TimelineDetailsView.ts
@@ -289,7 +289,7 @@ if (TimelineSelection.isSyntheticNetworkRequestDetailsEventSelection(selectionObject)) { const networkRequest = selectionObject; const maybeTarget = targetForEvent(this.#traceEngineData, networkRequest); - await this.#networkRequestDetails.setData(networkRequest, maybeTarget); + await this.#networkRequestDetails.setData(this.#traceEngineData, networkRequest, maybeTarget); this.setContent(this.#networkRequestDetails); } else if (TimelineSelection.isTraceEventSelection(selectionObject)) { const event = selectionObject;
diff --git a/front_end/panels/timeline/components/NetworkRequestDetails.test.ts b/front_end/panels/timeline/components/NetworkRequestDetails.test.ts index 7e2f803..ef0ca9a 100644 --- a/front_end/panels/timeline/components/NetworkRequestDetails.test.ts +++ b/front_end/panels/timeline/components/NetworkRequestDetails.test.ts
@@ -22,7 +22,7 @@ const details = new TimelineComponents.NetworkRequestDetails.NetworkRequestDetails(new Components.Linkifier.Linkifier()); - await details.setData(cssRequest, Timeline.TargetForEvent.targetForEvent(traceData, cssRequest)); + await details.setData(traceData, cssRequest, Timeline.TargetForEvent.targetForEvent(traceData, cssRequest)); if (!details.shadowRoot) { throw new Error('Could not find expected element to test.'); @@ -48,6 +48,10 @@ {title: 'Mime Type', value: 'text/css'}, {title: 'Encoded Data', value: ' (from cache)'}, {title: 'Decoded Body', value: '96 B'}, + { + title: 'Initiated by', + value: 'chromedevtools.github.io/performance-stories/lcp-web-font/index.html', + }, {title: 'From cache', value: 'Yes'}, {title: 'Duration', value: durationInnerText}, ],
diff --git a/front_end/panels/timeline/components/NetworkRequestDetails.ts b/front_end/panels/timeline/components/NetworkRequestDetails.ts index abd85ea..c5bf05d 100644 --- a/front_end/panels/timeline/components/NetworkRequestDetails.ts +++ b/front_end/panels/timeline/components/NetworkRequestDetails.ts
@@ -115,6 +115,7 @@ #maybeTarget: SDK.Target.Target|null = null; #requestPreviewElements = new WeakMap<TraceEngine.Types.TraceEvents.SyntheticNetworkRequest, HTMLImageElement>(); #linkifier: LegacyComponents.Linkifier.Linkifier; + #traceParsedData: TraceEngine.Handlers.Types.TraceParseData|null = null; constructor(linkifier: LegacyComponents.Linkifier.Linkifier) { super(); this.#linkifier = linkifier; @@ -125,11 +126,13 @@ } async setData( + traceParsedData: TraceEngine.Handlers.Types.TraceParseData, networkRequest: TraceEngine.Types.TraceEvents.SyntheticNetworkRequest, maybeTarget: SDK.Target.Target|null): Promise<void> { - if (this.#networkRequest === networkRequest) { + if (this.#networkRequest === networkRequest && traceParsedData === this.#traceParsedData) { return; } + this.#traceParsedData = traceParsedData; this.#networkRequest = networkRequest; this.#maybeTarget = maybeTarget; await this.#render(); @@ -260,14 +263,33 @@ return null; } - const topFrame = TraceEngine.Helpers.Trace.getZeroIndexedStackTraceForEvent(this.#networkRequest)?.at(0) ?? null; - if (topFrame) { - const link = this.#linkifier.maybeLinkifyConsoleCallFrame( - this.#maybeTarget, topFrame, {tabStop: true, inlineFrameIndex: 0, showColumnNumber: true}); + const hasStackTrace = TraceEngine.Helpers.Trace.stackTraceForEvent(this.#networkRequest) !== null; + + // If we have a stack trace, that is the most reliable way to get the initiator data and display a link to the source. + if (hasStackTrace) { + const topFrame = TraceEngine.Helpers.Trace.getZeroIndexedStackTraceForEvent(this.#networkRequest)?.at(0) ?? null; + if (topFrame) { + const link = this.#linkifier.maybeLinkifyConsoleCallFrame( + this.#maybeTarget, topFrame, {tabStop: true, inlineFrameIndex: 0, showColumnNumber: true}); + if (link) { + return this.#renderRow(i18nString(UIStrings.initiatedBy), link); + } + } + } + // If we do not, we can see if the network handler found an initiator and try to link by URL + const initiator = this.#traceParsedData?.NetworkRequests.eventToInitiator.get(this.#networkRequest); + if (initiator) { + const link = this.#linkifier.maybeLinkifyScriptLocation( + this.#maybeTarget, + null, // this would be the scriptId, but we don't have one. The linkifier will fallback to using the URL. + initiator.args.data.url as Platform.DevToolsPath.UrlString, + undefined, // line number + ); if (link) { return this.#renderRow(i18nString(UIStrings.initiatedBy), link); } } + return null; }
diff --git a/front_end/ui/components/docs/performance_panel/network_request_details.ts b/front_end/ui/components/docs/performance_panel/network_request_details.ts index 248aa43..3940c4d 100644 --- a/front_end/ui/components/docs/performance_panel/network_request_details.ts +++ b/front_end/ui/components/docs/performance_panel/network_request_details.ts
@@ -27,7 +27,7 @@ const maybeTarget = Timeline.TargetForEvent.targetForEvent(traceData, networkEvent); const details = new TimelineComponents.NetworkRequestDetails.NetworkRequestDetails(detailsLinkifier); - await details.setData(networkEvent, maybeTarget); + await details.setData(traceData, networkEvent, maybeTarget); container.appendChild(details); }
diff --git a/front_end/ui/visual_logging/KnownContextValues.ts b/front_end/ui/visual_logging/KnownContextValues.ts index cccb72f..f8ab963 100644 --- a/front_end/ui/visual_logging/KnownContextValues.ts +++ b/front_end/ui/visual_logging/KnownContextValues.ts
@@ -3017,6 +3017,7 @@ 'timeline.thread.other', 'timeline.thread.pool', 'timeline.thread.rasterizer', + 'timeline.thread.worker', 'timeline.timings', 'timeline.toggle-insight', 'timeline.toggle-recording',