Skip to content

Commit f4a41da

Browse files
Nancy LiDevtools-frontend LUCI CQ
authored andcommitted
[RPP Insight] Add some skeleton code for long critical network tree insight
This CL adds the skeleton code for the insight model and insight component, it doesn't have any functionality, just the code compiles successfully. Also this insight will be behind the flag. Bug: 372897712 Change-Id: I0c234b7f7eee0144df729ce4b0eab524b0eefc32 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6179489 Reviewed-by: Jack Franklin <[email protected]> Commit-Queue: Nancy Li <[email protected]>
1 parent 887c6ad commit f4a41da

File tree

11 files changed

+126
-1
lines changed

11 files changed

+126
-1
lines changed

config/gni/devtools_grd_files.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ grd_files_debug_sources = [
11141114
"front_end/models/trace/insights/InteractionToNextPaint.js",
11151115
"front_end/models/trace/insights/LCPDiscovery.js",
11161116
"front_end/models/trace/insights/LCPPhases.js",
1117+
"front_end/models/trace/insights/LongCriticalNetworkTree.js",
11171118
"front_end/models/trace/insights/Models.js",
11181119
"front_end/models/trace/insights/RenderBlocking.js",
11191120
"front_end/models/trace/insights/SlowCSSSelector.js",
@@ -1869,6 +1870,7 @@ grd_files_debug_sources = [
18691870
"front_end/panels/timeline/components/insights/InteractionToNextPaint.js",
18701871
"front_end/panels/timeline/components/insights/LCPDiscovery.js",
18711872
"front_end/panels/timeline/components/insights/LCPPhases.js",
1873+
"front_end/panels/timeline/components/insights/LongCriticalNetworkTree.js",
18721874
"front_end/panels/timeline/components/insights/NodeLink.js",
18731875
"front_end/panels/timeline/components/insights/RenderBlocking.js",
18741876
"front_end/panels/timeline/components/insights/SidebarInsight.js",

front_end/models/trace/Processor.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ describeWithEnvironment('TraceProcessor', function() {
408408
'DOMSize',
409409
'ThirdParties',
410410
'SlowCSSSelector',
411+
'LongCriticalNetworkTree',
411412
]);
412413

413414
const orderWithMetadata = await getInsightOrder(true);
@@ -425,6 +426,7 @@ describeWithEnvironment('TraceProcessor', function() {
425426
'DOMSize',
426427
'ThirdParties',
427428
'SlowCSSSelector',
429+
'LongCriticalNetworkTree',
428430
]);
429431
});
430432
});

front_end/models/trace/Processor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ export class TraceProcessor extends EventTarget {
365365
DOMSize: null,
366366
ThirdParties: null,
367367
SlowCSSSelector: null,
368+
LongCriticalNetworkTree: null,
368369
};
369370

370371
// Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.
@@ -573,7 +574,7 @@ export class TraceProcessor extends EventTarget {
573574
/**
574575
* Some Handlers need data provided by others. Dependencies of a handler handler are
575576
* declared in the `deps` field.
576-
* @returns A map from trace event handler name to trace event hander whose entries
577+
* @returns A map from trace event handler name to trace event handler whose entries
577578
* iterate in such a way that each handler is visited after its dependencies.
578579
*/
579580
export function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):

front_end/models/trace/insights/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ devtools_module("insights") {
1717
"InteractionToNextPaint.ts",
1818
"LCPDiscovery.ts",
1919
"LCPPhases.ts",
20+
"LongCriticalNetworkTree.ts",
2021
"Models.ts",
2122
"RenderBlocking.ts",
2223
"SlowCSSSelector.ts",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2025 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import * as i18n from '../../../core/i18n/i18n.js';
6+
import type * as Types from '../types/types.js';
7+
8+
import {InsightCategory, type InsightModel, type InsightSetContext, type RequiredData} from './types.js';
9+
10+
const UIStrings = {
11+
/**
12+
* @description Title of an insight that recommends avoiding chaining critical requests.
13+
*/
14+
title: 'Long critical network tree',
15+
/**
16+
* @description Description of an insight that recommends avoiding chaining critical requests.
17+
*/
18+
description:
19+
'[Avoid chaining critical requests](https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains) by reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load.',
20+
};
21+
22+
const str_ = i18n.i18n.registerUIStrings('models/trace/insights/LongCriticalNetworkTree.ts', UIStrings);
23+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
24+
25+
export type LongCriticalNetworkTreeInsightModel = InsightModel<{
26+
longChains: Types.Events.SyntheticNetworkRequest[][],
27+
}>;
28+
29+
export function deps(): ['NetworkRequests'] {
30+
return ['NetworkRequests'];
31+
}
32+
33+
function finalize(
34+
partialModel: Omit<LongCriticalNetworkTreeInsightModel, 'title'|'description'|'category'|'shouldShow'>):
35+
LongCriticalNetworkTreeInsightModel {
36+
return {
37+
title: i18nString(UIStrings.title),
38+
description: i18nString(UIStrings.description),
39+
category: InsightCategory.LCP,
40+
shouldShow: partialModel.longChains.length > 0,
41+
...partialModel,
42+
};
43+
}
44+
45+
export function generateInsight(
46+
_parsedTrace: RequiredData<typeof deps>, _context: InsightSetContext): LongCriticalNetworkTreeInsightModel {
47+
return finalize({
48+
longChains: [],
49+
});
50+
}

front_end/models/trace/insights/Models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * as ImageDelivery from './ImageDelivery.js';
1010
export * as InteractionToNextPaint from './InteractionToNextPaint.js';
1111
export * as LCPDiscovery from './LCPDiscovery.js';
1212
export * as LCPPhases from './LCPPhases.js';
13+
export * as LongCriticalNetworkTree from './LongCriticalNetworkTree.js';
1314
export * as RenderBlocking from './RenderBlocking.js';
1415
export * as SlowCSSSelector from './SlowCSSSelector.js';
1516
export * as ThirdParties from './ThirdParties.js';

front_end/panels/timeline/components/SidebarSingleInsightSet.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ describeWithEnvironment('SidebarSingleInsightSet', () => {
163163
'Optimize viewport for mobile',
164164
'Optimize DOM size',
165165
'CSS Selector costs',
166+
'Long critical network tree',
166167
]);
167168

168169
const passedInsightTitles = getPassedInsights(component).flatMap(component => {
@@ -176,6 +177,7 @@ describeWithEnvironment('SidebarSingleInsightSet', () => {
176177
'Optimize viewport for mobile',
177178
'Optimize DOM size',
178179
'CSS Selector costs',
180+
'Long critical network tree',
179181
]);
180182
});
181183

front_end/panels/timeline/components/SidebarSingleInsightSet.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface SidebarSingleInsightSetData {
5555
* users. */
5656
const EXPERIMENTAL_INSIGHTS: ReadonlySet<string> = new Set([
5757
'FontDisplay',
58+
'LongCriticalNetworkTree',
5859
]);
5960

6061
type InsightNameToComponentMapping =
@@ -74,6 +75,7 @@ const INSIGHT_NAME_TO_COMPONENT: InsightNameToComponentMapping = {
7475
InteractionToNextPaint: Insights.InteractionToNextPaint.InteractionToNextPaint,
7576
LCPDiscovery: Insights.LCPDiscovery.LCPDiscovery,
7677
LCPPhases: Insights.LCPPhases.LCPPhases,
78+
LongCriticalNetworkTree: Insights.LongCriticalNetworkTree.LongCriticalNetworkTree,
7779
RenderBlocking: Insights.RenderBlocking.RenderBlocking,
7880
SlowCSSSelector: Insights.SlowCSSSelector.SlowCSSSelector,
7981
ThirdParties: Insights.ThirdParties.ThirdParties,

front_end/panels/timeline/components/insights/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ devtools_module("insights") {
2727
"InteractionToNextPaint.ts",
2828
"LCPDiscovery.ts",
2929
"LCPPhases.ts",
30+
"LongCriticalNetworkTree.ts",
3031
"NodeLink.ts",
3132
"RenderBlocking.ts",
3233
"SidebarInsight.ts",
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2025 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import '../../../../ui/components/icon_button/icon_button.js';
6+
7+
import * as i18n from '../../../../core/i18n/i18n.js';
8+
import type {LongCriticalNetworkTreeInsightModel} from '../../../../models/trace/insights/LongCriticalNetworkTree.js';
9+
import * as LitHtml from '../../../../ui/lit-html/lit-html.js';
10+
import type * as Overlays from '../../overlays/overlays.js';
11+
12+
import {BaseInsightComponent} from './BaseInsightComponent.js';
13+
14+
const UIStrings = {
15+
/**
16+
* @description Text status indicating that there isn't long chaining critical network requests.
17+
*/
18+
noLongCriticalNetworkTree: 'No rendering tasks impacted by long critical network tree',
19+
};
20+
21+
const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/insights/LongCriticalNetworkTree.ts', UIStrings);
22+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
23+
24+
const {html} = LitHtml;
25+
26+
export class LongCriticalNetworkTree extends BaseInsightComponent<LongCriticalNetworkTreeInsightModel> {
27+
static override readonly litTagName = LitHtml.StaticHtml.literal`devtools-performance-long-critical-network-tree`;
28+
override internalName: string = 'long-critical-network-tree';
29+
30+
override createOverlays(): Overlays.Overlays.TimelineOverlay[] {
31+
if (!this.model) {
32+
return [];
33+
}
34+
35+
return this.model.longChains.flat().map(entry => ({
36+
type: 'ENTRY_OUTLINE',
37+
entry,
38+
outlineReason: 'ERROR',
39+
}));
40+
}
41+
42+
override renderContent(): LitHtml.LitTemplate {
43+
if (!this.model) {
44+
return LitHtml.nothing;
45+
}
46+
47+
if (!this.model.longChains.length) {
48+
return html`<div class="insight-section">${i18nString(UIStrings.noLongCriticalNetworkTree)}</div>`;
49+
}
50+
51+
return LitHtml.nothing;
52+
}
53+
}
54+
55+
declare global {
56+
interface HTMLElementTagNameMap {
57+
'devtools-performance-long-critical-network-tree': LongCriticalNetworkTree;
58+
}
59+
}
60+
61+
customElements.define('devtools-performance-long-critical-network-tree', LongCriticalNetworkTree);

0 commit comments

Comments
 (0)