Skip to content

Commit 4325280

Browse files
finnurbrekiDevtools-frontend LUCI CQ
authored andcommitted
[AskAi]: Agentize the Viewport insight.
Example response: https://screenshot.googleplex.com/B3zhkar8WSBzr6n Fixed: 425275378 Change-Id: I4c22c086d40a87711d7984cb78954a076cda50b5 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6917690 Commit-Queue: Finnur Thorarinsson <[email protected]> Reviewed-by: Connor Clark <[email protected]>
1 parent d5d7b49 commit 4325280

File tree

5 files changed

+100
-2
lines changed

5 files changed

+100
-2
lines changed

front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,3 +1026,41 @@ The following list contains the largest amount spent by a 3rd party script on th
10261026
## External resources:
10271027
- https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/
10281028
=== end content
1029+
1030+
Title: PerformanceInsightFormatter Viewport serializes correctly when there are no results
1031+
Content:
1032+
## Insight Title: Optimize viewport for mobile
1033+
1034+
## Insight Summary:
1035+
The insight identifies web pages that are not specifying the viewport meta tag for mobile devies, which avoids the artificial 300-350ms delay designed to help differentiate between tap and double-click.
1036+
1037+
## Detailed analysis:
1038+
The webpage is not optimized for mobile viewing.
1039+
1040+
The viewport meta tag was found: `width=device-width, initial-scale=0.25`.
1041+
1042+
## Estimated savings: INP 0 ms
1043+
1044+
## External resources:
1045+
- https://developer.chrome.com/blog/300ms-tap-delay-gone-away/
1046+
=== end content
1047+
1048+
Title: PerformanceInsightFormatter Viewport serializes the correct details showing viewport problems on mobile
1049+
Content:
1050+
## Insight Title: Optimize viewport for mobile
1051+
1052+
## Insight Summary:
1053+
The insight identifies web pages that are not specifying the viewport meta tag for mobile devies, which avoids the artificial 300-350ms delay designed to help differentiate between tap and double-click.
1054+
1055+
## Detailed analysis:
1056+
The webpage is not optimized for mobile viewing.
1057+
1058+
The viewport meta tag is missing.
1059+
1060+
Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.
1061+
1062+
## Estimated savings: none
1063+
1064+
## External resources:
1065+
- https://developer.chrome.com/blog/300ms-tap-delay-gone-away/
1066+
=== end content

front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,4 +496,26 @@ describeWithEnvironment('PerformanceInsightFormatter', () => {
496496
snapshotTester.assert(this, output);
497497
});
498498
});
499+
500+
describe('Viewport', () => {
501+
it('serializes correctly when there are no results', async function() {
502+
const {parsedTrace, insights} = await TraceLoader.traceEngine(this, 'image-delivery.json.gz');
503+
assert.isOk(insights);
504+
const firstNav = getFirstOrError(parsedTrace.Meta.navigationsByNavigationId.values());
505+
const insight = getInsightOrError('Viewport', insights, firstNav);
506+
const formatter = new PerformanceInsightFormatter(parsedTrace, insight);
507+
const output = formatter.formatInsight();
508+
snapshotTester.assert(this, output);
509+
});
510+
511+
it('serializes the correct details showing viewport problems on mobile', async function() {
512+
const {parsedTrace, insights} = await TraceLoader.traceEngine(this, 'simple-js-program.json.gz');
513+
assert.isOk(insights);
514+
const firstNav = getFirstOrError(parsedTrace.Meta.navigationsByNavigationId.values());
515+
const insight = getInsightOrError('Viewport', insights, firstNav);
516+
const formatter = new PerformanceInsightFormatter(parsedTrace, insight);
517+
const output = formatter.formatInsight();
518+
snapshotTester.assert(this, output);
519+
});
520+
});
499521
});

front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,32 @@ export class PerformanceInsightFormatter {
488488
return output;
489489
}
490490

491+
/**
492+
* Create an AI prompt string out of the Viewport [Mobile] Insight model to use with Ask AI.
493+
* Note: This function accesses the UIStrings within Viewport to help build the
494+
* AI prompt, but does not (and should not) call i18nString to localize these strings. They
495+
* should all be sent in English (at least for now).
496+
* @param insight The Network Dependency Tree Insight Model to query.
497+
* @returns a string formatted for sending to Ask AI.
498+
*/
499+
formatViewportInsight(insight: Trace.Insights.Models.Viewport.ViewportInsightModel): string {
500+
let output = '';
501+
502+
output += 'The webpage is ' + (insight.mobileOptimized ? 'already' : 'not') + ' optimized for mobile viewing.\n';
503+
504+
const hasMetaTag = insight.viewportEvent;
505+
if (hasMetaTag) {
506+
output += `\nThe viewport meta tag was found: \`${insight.viewportEvent?.args?.data.content}\`.`;
507+
} else {
508+
output += `\nThe viewport meta tag is missing.`;
509+
}
510+
511+
if (!hasMetaTag) {
512+
output += '\n\n' + Trace.Insights.Models.Viewport.UIStrings.description;
513+
}
514+
return output;
515+
}
516+
491517
/**
492518
* Formats and outputs the insight's data.
493519
* Pass `{headingLevel: X}` to determine what heading level to use for the
@@ -762,6 +788,10 @@ ${filesFormatted}`;
762788
return this.formatThirdPartiesInsight(this.#insight);
763789
}
764790

791+
if (Trace.Insights.Models.Viewport.isViewportInsight(this.#insight)) {
792+
return this.formatViewportInsight(this.#insight);
793+
}
794+
765795
return '';
766796
}
767797

@@ -817,7 +847,7 @@ ${filesFormatted}`;
817847
case 'ThirdParties':
818848
return '- https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/';
819849
case 'Viewport':
820-
return '';
850+
return '- https://developer.chrome.com/blog/300ms-tap-delay-gone-away/';
821851
case 'Cache':
822852
return '';
823853
case 'ModernHTTP':
@@ -891,7 +921,7 @@ It is important that all of these checks pass to minimize the delay between the
891921
case 'ThirdParties':
892922
return 'This insight analyzes the performance impact of resources loaded from third-party servers and aggregates the performance cost, in terms of download transfer sizes and total amount of time that third party scripts spent executing on the main thread.';
893923
case 'Viewport':
894-
return '';
924+
return 'The insight identifies web pages that are not specifying the viewport meta tag for mobile devies, which avoids the artificial 300-350ms delay designed to help differentiate between tap and double-click.';
895925
case 'Cache':
896926
return '';
897927
case 'ModernHTTP':

front_end/models/trace/insights/Viewport.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ function finalize(partialModel: PartialInsightModel<ViewportInsightModel>): View
5252
};
5353
}
5454

55+
export function isViewportInsight(model: InsightModel): model is ViewportInsightModel {
56+
return model.insightKey === InsightKeys.VIEWPORT;
57+
}
58+
5559
export function generateInsight(
5660
parsedTrace: Handlers.Types.ParsedTrace, context: InsightSetContext): ViewportInsightModel {
5761
const viewportEvent = parsedTrace.UserInteractions.parseMetaViewportEvents.find(event => {

front_end/panels/timeline/components/insights/Viewport.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export class Viewport extends BaseInsightComponent<ViewportInsightModel> {
1616
static override readonly litTagName = Lit.StaticHtml.literal`devtools-performance-viewport`;
1717
override internalName = 'viewport';
1818

19+
protected override hasAskAiSupport(): boolean {
20+
return true;
21+
}
22+
1923
override getEstimatedSavingsTime(): Trace.Types.Timing.Milli|null {
2024
return this.model?.metricSavings?.INP ?? null;
2125
}

0 commit comments

Comments
 (0)