[RPP insights] Fix the auto-scroll to the top of Network Dependency Tree insight
Screenshot: https://screenshot.googleplex.com/49BdxA9iogWgtUf
Bug: 414571447
Change-Id: I473ba79cdbdacf686b8bfde305163f91de644c38
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6494824
Commit-Queue: Nancy Li <[email protected]>
Reviewed-by: Connor Clark <[email protected]>
diff --git a/front_end/models/trace/insights/NetworkDependencyTree.ts b/front_end/models/trace/insights/NetworkDependencyTree.ts
index fc8e796..9229249 100644
--- a/front_end/models/trace/insights/NetworkDependencyTree.ts
+++ b/front_end/models/trace/insights/NetworkDependencyTree.ts
@@ -45,6 +45,10 @@
* the browser must download before it can render the page.
*/
maxCriticalPathLatency: 'Max critical path latency:',
+ /** Label for a column in a data table; entries will be the network request */
+ columnRequest: 'Request',
+ /** Label for a column in a data table; entries will be the time from main document till current network request. */
+ columnTime: 'Time',
} as const;
const str_ = i18n.i18n.registerUIStrings('models/trace/insights/NetworkDependencyTree.ts', UIStrings);
diff --git a/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts b/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts
index e293302..81b5e06 100644
--- a/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts
+++ b/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import './Table.js';
import '../../../../ui/components/icon_button/icon_button.js';
import * as i18n from '../../../../core/i18n/i18n.js';
@@ -15,6 +16,7 @@
import {BaseInsightComponent} from './BaseInsightComponent.js';
import {eventRef} from './EventRef.js';
import networkDependencyTreeInsightStyles from './networkDependencyTreeInsight.css.js';
+import type {TableData, TableDataRow} from './Table.js';
const {UIStrings, i18nString} = Trace.Insights.Models.NetworkDependencyTree;
@@ -47,59 +49,62 @@
return overlays;
}
- #onMouseOver(relatedRequests: Set<Trace.Types.Events.SyntheticNetworkRequest>): void {
- this.#relatedRequests = relatedRequests;
- const overlays = this.#createOverlayForChain(this.#relatedRequests);
- this.toggleTemporaryOverlays(overlays, {
- // The trace window doesn't need to be updated because the request is being hovered.
- updateTraceWindow: false,
+ #renderNetworkTreeRow(node: CriticalRequestNode): Lit.LitTemplate {
+ const requestStyles = Lit.Directives.styleMap({
+ display: 'flex',
+ '--override-timeline-link-text-color': node.isLongest ? 'var(--sys-color-error)' : '',
+ color: node.isLongest ? 'var(--sys-color-error)' : '',
+ backgroundColor: this.#relatedRequests?.has(node.request) ? 'var(--sys-color-state-hover-on-subtle)' : '',
});
- this.scheduleRender();
- }
-
- #onMouseOut(): void {
- this.#relatedRequests = null;
- this.toggleTemporaryOverlays(null, {
- updateTraceWindow: false,
+ const urlStyles = Lit.Directives.styleMap({
+ flex: 'auto',
});
- this.scheduleRender();
- }
- renderTree(nodes: CriticalRequestNode[]): Lit.LitTemplate|null {
- if (nodes.length === 0) {
- return null;
- }
// clang-format off
return html`
- <ul>
- ${nodes.map(({request, timeFromInitialRequest, children, isLongest, relatedRequests}) => {
- const hasChildren = children.length > 0;
-
- const requestClasses = Lit.Directives.classMap({
- request: true,
- longest: Boolean(isLongest),
- highlighted: this.#relatedRequests?.has(request) ?? false,
- });
-
- return html`
- <li>
- <div class=${requestClasses}
- @mouseover=${this.#onMouseOver.bind(this, relatedRequests)}
- @mouseout=${this.#onMouseOut.bind(this)}>
- <span class="url">${eventRef(request)}</span>
- <span class="chain-time">
- ${i18n.TimeUtilities.formatMicroSecondsTime(Trace.Types.Timing.Micro(timeFromInitialRequest))}
- </span>
- </div>
- </li>
- ${hasChildren ? html`${this.renderTree(children)}` : Lit.nothing}
- `;
- })}
- </ul>`;
+ <div style=${requestStyles}>
+ <span style=${urlStyles}>${eventRef(node.request)}</span>
+ <span>
+ ${i18n.TimeUtilities.formatMicroSecondsTime(Trace.Types.Timing.Micro(node.timeFromInitialRequest))}
+ </span>
+ </div>
+ `;
// clang-format on
}
- override renderContent(): Lit.LitTemplate {
+ #mapNetworkDependencyToRow(node: CriticalRequestNode): TableDataRow {
+ return {
+ values: [this.#renderNetworkTreeRow(node)],
+ overlays: this.#createOverlayForChain(node.relatedRequests),
+ subRows: node.children.map(child => this.#mapNetworkDependencyToRow(child)),
+ };
+ }
+
+ #renderNetworkDependencyTree(nodes: CriticalRequestNode[]): Lit.LitTemplate|null {
+ if (nodes.length === 0) {
+ return null;
+ }
+
+ const rows: TableDataRow[] = [{
+ // Add one empty row so the main document request can also has a left border
+ values: [Lit.nothing],
+ subRows: nodes.map(node => this.#mapNetworkDependencyToRow(node))
+ }];
+
+ // clang-format off
+ return html`
+ <devtools-performance-table
+ .data=${{
+ insight: this,
+ headers: [i18nString(UIStrings.columnRequest), i18nString(UIStrings.columnTime)],
+ rows,
+ } as TableData}>
+ </devtools-performance-table>
+ `;
+ // clang-format on
+ }
+
+ #renderNetworkTreeSection(): Lit.LitTemplate {
if (!this.model) {
return Lit.nothing;
}
@@ -122,13 +127,19 @@
<br>
<span class='longest'> ${i18n.TimeUtilities.formatMicroSecondsTime((this.model.maxTime))}</span>
</div>
-
- <!-- a divider is added here, through |tree-view| element's border-top -->
- <div class="tree-view">${this.renderTree(this.model.rootNodes)} </div>
+ </div>
+ <div class="insight-section">
+ ${this.#renderNetworkDependencyTree(this.model.rootNodes)}
</div>
`;
// clang-format on
}
+
+ override renderContent(): Lit.LitTemplate {
+ return html`
+ ${this.#renderNetworkTreeSection()}
+ `;
+ }
}
function getAllOverlays(nodes: CriticalRequestNode[], overlays: Overlays.Overlays.TimelineOverlay[]): void {
diff --git a/front_end/panels/timeline/components/insights/Table.ts b/front_end/panels/timeline/components/insights/Table.ts
index f835832..e7c51e6 100644
--- a/front_end/panels/timeline/components/insights/Table.ts
+++ b/front_end/panels/timeline/components/insights/Table.ts
@@ -113,7 +113,7 @@
this.#headers = data.headers;
this.#rows = data.rows;
// If this table isn't interactive, don't attach mouse listeners or use CSS :hover.
- this.#interactive = this.#rows.some(row => row.overlays);
+ this.#interactive = this.#rows.some(row => row.overlays || row.subRows);
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
}
diff --git a/front_end/panels/timeline/components/insights/networkDependencyTreeInsight.css b/front_end/panels/timeline/components/insights/networkDependencyTreeInsight.css
index 8029975..b1d7eed 100644
--- a/front_end/panels/timeline/components/insights/networkDependencyTreeInsight.css
+++ b/front_end/panels/timeline/components/insights/networkDependencyTreeInsight.css
@@ -15,45 +15,4 @@
color: var(--sys-color-error);
}
}
-
- .tree-view {
- border-top: var(--sys-size-1) solid var(--sys-color-divider);
- padding-top: var(--sys-size-5);
- margin-top: var(--sys-size-5);
-
- ul:first-child{
- padding-left: 0;
- }
-
- ul:not(:first-child){
- border-left: var(--sys-size-1) solid var(--sys-color-tonal-outline);
- list-style: none;
- padding-left: var(--sys-size-5)
- }
-
- li {
- border-left: var(--sys-size-1) solid var(--sys-color-tonal-outline);
- list-style: none;
- min-height: var(--sys-size-8);
- padding: var(--sys-size-2) 0 var(--sys-size-2) var(--sys-size-5);
-
- .request {
- display: flex;
-
- &.longest {
- --override-timeline-link-text-color: var(--sys-color-error);
-
- color: var(--sys-color-error);
- }
-
- &.highlighted {
- background-color: var(--sys-color-state-hover-on-subtle);
- }
-
- .url {
- flex: auto;
- }
- }
- }
- }
}