lighthouse 12.3.0-dev.20250204 → 12.3.0-dev.20250206

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 (53) hide show
  1. package/core/audits/audit.d.ts +5 -0
  2. package/core/audits/audit.js +11 -0
  3. package/core/audits/insights/README.md +3 -0
  4. package/core/audits/insights/cls-culprits-insight.d.ts +11 -0
  5. package/core/audits/insights/cls-culprits-insight.js +52 -0
  6. package/core/audits/insights/document-latency-insight.d.ts +11 -0
  7. package/core/audits/insights/document-latency-insight.js +47 -0
  8. package/core/audits/insights/dom-size-insight.d.ts +11 -0
  9. package/core/audits/insights/dom-size-insight.js +84 -0
  10. package/core/audits/insights/font-display-insight.d.ts +11 -0
  11. package/core/audits/insights/font-display-insight.js +52 -0
  12. package/core/audits/insights/forced-reflow-insight.d.ts +11 -0
  13. package/core/audits/insights/forced-reflow-insight.js +52 -0
  14. package/core/audits/insights/image-delivery-insight.d.ts +11 -0
  15. package/core/audits/insights/image-delivery-insight.js +52 -0
  16. package/core/audits/insights/insight-audit.d.ts +16 -0
  17. package/core/audits/insights/insight-audit.js +88 -0
  18. package/core/audits/insights/interaction-to-next-paint-insight.d.ts +11 -0
  19. package/core/audits/insights/interaction-to-next-paint-insight.js +52 -0
  20. package/core/audits/insights/lcp-discovery-insight.d.ts +11 -0
  21. package/core/audits/insights/lcp-discovery-insight.js +47 -0
  22. package/core/audits/insights/lcp-phases-insight.d.ts +11 -0
  23. package/core/audits/insights/lcp-phases-insight.js +52 -0
  24. package/core/audits/insights/long-critical-network-tree-insight.d.ts +11 -0
  25. package/core/audits/insights/long-critical-network-tree-insight.js +52 -0
  26. package/core/audits/insights/render-blocking-insight.d.ts +11 -0
  27. package/core/audits/insights/render-blocking-insight.js +56 -0
  28. package/core/audits/insights/slow-css-selector-insight.d.ts +11 -0
  29. package/core/audits/insights/slow-css-selector-insight.js +52 -0
  30. package/core/audits/insights/third-parties-insight.d.ts +11 -0
  31. package/core/audits/insights/third-parties-insight.js +52 -0
  32. package/core/audits/insights/viewport-insight.d.ts +11 -0
  33. package/core/audits/insights/viewport-insight.js +53 -0
  34. package/core/computed/metrics/lantern-metric.js +5 -1
  35. package/core/computed/trace-engine-result.d.ts +0 -4
  36. package/core/computed/trace-engine-result.js +0 -26
  37. package/core/config/default-config.js +35 -0
  38. package/core/gather/gatherers/trace-elements.d.ts +8 -0
  39. package/core/gather/gatherers/trace-elements.js +71 -1
  40. package/core/runner.js +2 -0
  41. package/dist/report/bundle.esm.js +38 -3
  42. package/dist/report/flow.js +40 -5
  43. package/dist/report/standalone.js +38 -3
  44. package/package.json +4 -3
  45. package/report/assets/styles.css +35 -0
  46. package/report/renderer/components.js +1 -1
  47. package/report/renderer/details-renderer.d.ts +5 -0
  48. package/report/renderer/details-renderer.js +21 -0
  49. package/report/renderer/performance-category-renderer.js +24 -9
  50. package/shared/localization/locales/en-US.json +213 -0
  51. package/shared/localization/locales/en-XL.json +213 -0
  52. package/types/artifacts.d.ts +1 -1
  53. package/types/lhr/audit-details.d.ts +6 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js';
8
+
9
+ import {Audit} from '../audit.js';
10
+ import * as i18n from '../../lib/i18n/i18n.js';
11
+ import {adaptInsightToAuditProduct} from './insight-audit.js';
12
+
13
+ // eslint-disable-next-line max-len
14
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js', UIStrings);
15
+
16
+ class LCPDiscoveryInsight extends Audit {
17
+ /**
18
+ * @return {LH.Audit.Meta}
19
+ */
20
+ static get meta() {
21
+ return {
22
+ id: 'lcp-discovery-insight',
23
+ title: str_(UIStrings.title),
24
+ failureTitle: str_(UIStrings.title),
25
+ description: str_(UIStrings.description),
26
+ guidanceLevel: 3,
27
+ requiredArtifacts: ['traces', 'TraceElements'],
28
+ };
29
+ }
30
+
31
+ /**
32
+ * @param {LH.Artifacts} artifacts
33
+ * @param {LH.Audit.Context} context
34
+ * @return {Promise<LH.Audit.Product>}
35
+ */
36
+ static async audit(artifacts, context) {
37
+ return adaptInsightToAuditProduct(artifacts, context, 'LCPDiscovery', (insight) => {
38
+ if (!insight.checklist) {
39
+ return;
40
+ }
41
+
42
+ return Audit.makeChecklistDetails(insight.checklist);
43
+ });
44
+ }
45
+ }
46
+
47
+ export default LCPDiscoveryInsight;
@@ -0,0 +1,11 @@
1
+ export default LCPPhasesInsight;
2
+ declare class LCPPhasesInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=lcp-phases-insight.d.ts.map
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-unused-vars */ // TODO: remove once implemented.
2
+
3
+ /**
4
+ * @license
5
+ * Copyright 2025 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/LCPPhases.js';
10
+
11
+ import {Audit} from '../audit.js';
12
+ import * as i18n from '../../lib/i18n/i18n.js';
13
+ import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
14
+
15
+ // eslint-disable-next-line max-len
16
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/LCPPhases.js', UIStrings);
17
+
18
+ class LCPPhasesInsight extends Audit {
19
+ /**
20
+ * @return {LH.Audit.Meta}
21
+ */
22
+ static get meta() {
23
+ return {
24
+ id: 'lcp-phases-insight',
25
+ title: str_(UIStrings.title),
26
+ failureTitle: str_(UIStrings.title),
27
+ description: str_(UIStrings.description),
28
+ guidanceLevel: 3,
29
+ requiredArtifacts: ['traces', 'TraceElements'],
30
+ };
31
+ }
32
+
33
+ /**
34
+ * @param {LH.Artifacts} artifacts
35
+ * @param {LH.Audit.Context} context
36
+ * @return {Promise<LH.Audit.Product>}
37
+ */
38
+ static async audit(artifacts, context) {
39
+ // TODO: implement.
40
+ return adaptInsightToAuditProduct(artifacts, context, 'LCPPhases', (insight) => {
41
+ /** @type {LH.Audit.Details.Table['headings']} */
42
+ const headings = [
43
+ ];
44
+ /** @type {LH.Audit.Details.Table['items']} */
45
+ const items = [
46
+ ];
47
+ return Audit.makeTableDetails(headings, items);
48
+ });
49
+ }
50
+ }
51
+
52
+ export default LCPPhasesInsight;
@@ -0,0 +1,11 @@
1
+ export default LongCriticalNetworkTreeInsight;
2
+ declare class LongCriticalNetworkTreeInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=long-critical-network-tree-insight.d.ts.map
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-unused-vars */ // TODO: remove once implemented.
2
+
3
+ /**
4
+ * @license
5
+ * Copyright 2025 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/LongCriticalNetworkTree.js';
10
+
11
+ import {Audit} from '../audit.js';
12
+ import * as i18n from '../../lib/i18n/i18n.js';
13
+ import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
14
+
15
+ // eslint-disable-next-line max-len
16
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/LongCriticalNetworkTree.js', UIStrings);
17
+
18
+ class LongCriticalNetworkTreeInsight extends Audit {
19
+ /**
20
+ * @return {LH.Audit.Meta}
21
+ */
22
+ static get meta() {
23
+ return {
24
+ id: 'long-critical-network-tree-insight',
25
+ title: str_(UIStrings.title),
26
+ failureTitle: str_(UIStrings.title),
27
+ description: str_(UIStrings.description),
28
+ guidanceLevel: 3,
29
+ requiredArtifacts: ['traces', 'TraceElements'],
30
+ };
31
+ }
32
+
33
+ /**
34
+ * @param {LH.Artifacts} artifacts
35
+ * @param {LH.Audit.Context} context
36
+ * @return {Promise<LH.Audit.Product>}
37
+ */
38
+ static async audit(artifacts, context) {
39
+ // TODO: implement.
40
+ return adaptInsightToAuditProduct(artifacts, context, 'LongCriticalNetworkTree', (insight) => {
41
+ /** @type {LH.Audit.Details.Table['headings']} */
42
+ const headings = [
43
+ ];
44
+ /** @type {LH.Audit.Details.Table['items']} */
45
+ const items = [
46
+ ];
47
+ return Audit.makeTableDetails(headings, items);
48
+ });
49
+ }
50
+ }
51
+
52
+ export default LongCriticalNetworkTreeInsight;
@@ -0,0 +1,11 @@
1
+ export default RenderBlockingInsight;
2
+ declare class RenderBlockingInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=render-blocking-insight.d.ts.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/RenderBlocking.js';
8
+
9
+ import {Audit} from '../audit.js';
10
+ import * as i18n from '../../lib/i18n/i18n.js';
11
+ import {adaptInsightToAuditProduct} from './insight-audit.js';
12
+
13
+ // eslint-disable-next-line max-len
14
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js', UIStrings);
15
+
16
+ class RenderBlockingInsight extends Audit {
17
+ /**
18
+ * @return {LH.Audit.Meta}
19
+ */
20
+ static get meta() {
21
+ return {
22
+ id: 'render-blocking-insight',
23
+ title: str_(UIStrings.title),
24
+ failureTitle: str_(UIStrings.title),
25
+ description: str_(UIStrings.description),
26
+ guidanceLevel: 3,
27
+ requiredArtifacts: ['traces', 'TraceElements'],
28
+ };
29
+ }
30
+
31
+ /**
32
+ * @param {LH.Artifacts} artifacts
33
+ * @param {LH.Audit.Context} context
34
+ * @return {Promise<LH.Audit.Product>}
35
+ */
36
+ static async audit(artifacts, context) {
37
+ // TODO: show UIStrings.noRenderBlocking if nothing was blocking?
38
+ return adaptInsightToAuditProduct(artifacts, context, 'RenderBlocking', (insight) => {
39
+ /** @type {LH.Audit.Details.Table['headings']} */
40
+ const headings = [
41
+ {key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
42
+ {key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize)},
43
+ {key: 'wastedMs', valueType: 'timespanMs', label: str_(i18n.UIStrings.columnWastedMs)},
44
+ ];
45
+ /** @type {LH.Audit.Details.Table['items']} */
46
+ const items = insight.renderBlockingRequests.map(request => ({
47
+ url: request.args.data.url,
48
+ totalBytes: request.args.data.encodedDataLength,
49
+ wastedMs: insight.requestIdToWastedMs?.get(request.args.data.requestId),
50
+ }));
51
+ return Audit.makeTableDetails(headings, items);
52
+ });
53
+ }
54
+ }
55
+
56
+ export default RenderBlockingInsight;
@@ -0,0 +1,11 @@
1
+ export default SlowCSSSelectorInsight;
2
+ declare class SlowCSSSelectorInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=slow-css-selector-insight.d.ts.map
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-unused-vars */ // TODO: remove once implemented.
2
+
3
+ /**
4
+ * @license
5
+ * Copyright 2025 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/SlowCSSSelector.js';
10
+
11
+ import {Audit} from '../audit.js';
12
+ import * as i18n from '../../lib/i18n/i18n.js';
13
+ import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
14
+
15
+ // eslint-disable-next-line max-len
16
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/SlowCSSSelector.js', UIStrings);
17
+
18
+ class SlowCSSSelectorInsight extends Audit {
19
+ /**
20
+ * @return {LH.Audit.Meta}
21
+ */
22
+ static get meta() {
23
+ return {
24
+ id: 'slow-css-selector-insight',
25
+ title: str_(UIStrings.title),
26
+ failureTitle: str_(UIStrings.title),
27
+ description: str_(UIStrings.description),
28
+ guidanceLevel: 3,
29
+ requiredArtifacts: ['traces', 'TraceElements'],
30
+ };
31
+ }
32
+
33
+ /**
34
+ * @param {LH.Artifacts} artifacts
35
+ * @param {LH.Audit.Context} context
36
+ * @return {Promise<LH.Audit.Product>}
37
+ */
38
+ static async audit(artifacts, context) {
39
+ // TODO: implement.
40
+ return adaptInsightToAuditProduct(artifacts, context, 'SlowCSSSelector', (insight) => {
41
+ /** @type {LH.Audit.Details.Table['headings']} */
42
+ const headings = [
43
+ ];
44
+ /** @type {LH.Audit.Details.Table['items']} */
45
+ const items = [
46
+ ];
47
+ return Audit.makeTableDetails(headings, items);
48
+ });
49
+ }
50
+ }
51
+
52
+ export default SlowCSSSelectorInsight;
@@ -0,0 +1,11 @@
1
+ export default ThirdPartiesInsight;
2
+ declare class ThirdPartiesInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=third-parties-insight.d.ts.map
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-unused-vars */ // TODO: remove once implemented.
2
+
3
+ /**
4
+ * @license
5
+ * Copyright 2025 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+
9
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/ThirdParties.js';
10
+
11
+ import {Audit} from '../audit.js';
12
+ import * as i18n from '../../lib/i18n/i18n.js';
13
+ import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
14
+
15
+ // eslint-disable-next-line max-len
16
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js', UIStrings);
17
+
18
+ class ThirdPartiesInsight extends Audit {
19
+ /**
20
+ * @return {LH.Audit.Meta}
21
+ */
22
+ static get meta() {
23
+ return {
24
+ id: 'third-parties-insight',
25
+ title: str_(UIStrings.title),
26
+ failureTitle: str_(UIStrings.title),
27
+ description: str_(UIStrings.description),
28
+ guidanceLevel: 3,
29
+ requiredArtifacts: ['traces', 'TraceElements'],
30
+ };
31
+ }
32
+
33
+ /**
34
+ * @param {LH.Artifacts} artifacts
35
+ * @param {LH.Audit.Context} context
36
+ * @return {Promise<LH.Audit.Product>}
37
+ */
38
+ static async audit(artifacts, context) {
39
+ // TODO: implement.
40
+ return adaptInsightToAuditProduct(artifacts, context, 'ThirdParties', (insight) => {
41
+ /** @type {LH.Audit.Details.Table['headings']} */
42
+ const headings = [
43
+ ];
44
+ /** @type {LH.Audit.Details.Table['items']} */
45
+ const items = [
46
+ ];
47
+ return Audit.makeTableDetails(headings, items);
48
+ });
49
+ }
50
+ }
51
+
52
+ export default ThirdPartiesInsight;
@@ -0,0 +1,11 @@
1
+ export default ViewportInsight;
2
+ declare class ViewportInsight extends Audit {
3
+ /**
4
+ * @param {LH.Artifacts} artifacts
5
+ * @param {LH.Audit.Context} context
6
+ * @return {Promise<LH.Audit.Product>}
7
+ */
8
+ static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
9
+ }
10
+ import { Audit } from '../audit.js';
11
+ //# sourceMappingURL=viewport-insight.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/Viewport.js';
8
+
9
+ import {Audit} from '../audit.js';
10
+ import * as i18n from '../../lib/i18n/i18n.js';
11
+ import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
12
+
13
+ // eslint-disable-next-line max-len
14
+ const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js', UIStrings);
15
+
16
+ class ViewportInsight extends Audit {
17
+ /**
18
+ * @return {LH.Audit.Meta}
19
+ */
20
+ static get meta() {
21
+ return {
22
+ id: 'viewport-insight',
23
+ title: str_(UIStrings.title),
24
+ failureTitle: str_(UIStrings.title),
25
+ description: str_(UIStrings.description),
26
+ guidanceLevel: 3,
27
+ requiredArtifacts: ['traces', 'TraceElements'],
28
+ };
29
+ }
30
+
31
+ /**
32
+ * @param {LH.Artifacts} artifacts
33
+ * @param {LH.Audit.Context} context
34
+ * @return {Promise<LH.Audit.Product>}
35
+ */
36
+ static async audit(artifacts, context) {
37
+ return adaptInsightToAuditProduct(artifacts, context, 'Viewport', (insight) => {
38
+ const nodeId = insight.viewportEvent?.args.data.node_id;
39
+
40
+ /** @type {LH.Audit.Details.Table['headings']} */
41
+ const headings = [
42
+ {key: 'node', valueType: 'node', label: ''},
43
+ ];
44
+ /** @type {LH.Audit.Details.Table['items']} */
45
+ const items = [
46
+ {node: makeNodeItemForNodeId(artifacts.TraceElements, nodeId)},
47
+ ];
48
+ return Audit.makeTableDetails(headings, items);
49
+ });
50
+ }
51
+ }
52
+
53
+ export default ViewportInsight;
@@ -39,7 +39,11 @@ async function getComputationDataParamsFromTrace(data, context) {
39
39
  const graph = await PageDependencyGraph.request({...data, fromTrace: true}, context);
40
40
  const traceEngineResult = await TraceEngineResult.request(data, context);
41
41
  const frameId = traceEngineResult.data.Meta.mainFrameId;
42
- const navigationId = traceEngineResult.data.Meta.mainFrameNavigations[0].args.data.navigationId;
42
+ const navigationId = traceEngineResult.data.Meta.mainFrameNavigations[0].args.data?.navigationId;
43
+ if (!navigationId) {
44
+ throw new Error(`Lantern metrics could not be calculated due to missing navigation id`);
45
+ }
46
+
43
47
  const processedNavigation = Lantern.TraceEngineComputationData.createProcessedNavigation(
44
48
  traceEngineResult.data, frameId, navigationId);
45
49
  const simulator = data.simulator || (await LoadSimulator.request(data, context));
@@ -13,10 +13,6 @@ declare class TraceEngineResult {
13
13
  * @return {Promise<LH.Artifacts.TraceEngineResult>}
14
14
  */
15
15
  static runTraceEngine(traceEvents: LH.TraceEvent[]): Promise<LH.Artifacts.TraceEngineResult>;
16
- /**
17
- * @param {import('@paulirish/trace_engine/models/trace/insights/types.js').TraceInsightSets} insightSets
18
- */
19
- static localizeInsights(insightSets: import("@paulirish/trace_engine/models/trace/insights/types.js").TraceInsightSets): void;
20
16
  /**
21
17
  * @param {{trace: LH.Trace}} data
22
18
  * @param {LH.Artifacts.ComputedContext} context
@@ -4,7 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import * as i18n from '../lib/i18n/i18n.js';
8
7
  import * as TraceEngine from '../lib/trace-engine.js';
9
8
  import {makeComputedArtifact} from './computed-artifact.js';
10
9
  import {CumulativeLayoutShift} from './metrics/cumulative-layout-shift.js';
@@ -28,34 +27,9 @@ class TraceEngineResult {
28
27
  ), {});
29
28
  if (!processor.parsedTrace) throw new Error('No data');
30
29
  if (!processor.insights) throw new Error('No insights');
31
- this.localizeInsights(processor.insights);
32
30
  return {data: processor.parsedTrace, insights: processor.insights};
33
31
  }
34
32
 
35
- /**
36
- * @param {import('@paulirish/trace_engine/models/trace/insights/types.js').TraceInsightSets} insightSets
37
- */
38
- static localizeInsights(insightSets) {
39
- for (const insightSet of insightSets.values()) {
40
- for (const [name, model] of Object.entries(insightSet.model)) {
41
- if (model instanceof Error) {
42
- continue;
43
- }
44
-
45
- const key = `node_modules/@paulirish/trace_engine/models/trace/insights/${name}.js`;
46
- const str_ = i18n.createIcuMessageFn(key, {
47
- title: model.title,
48
- description: model.description,
49
- });
50
-
51
- // @ts-expect-error coerce to string, should be fine
52
- model.title = str_(model.title);
53
- // @ts-expect-error coerce to string, should be fine
54
- model.description = str_(model.description);
55
- }
56
- }
57
- }
58
-
59
33
  /**
60
34
  * @param {{trace: LH.Trace}} data
61
35
  * @param {LH.Artifacts.ComputedContext} context
@@ -15,6 +15,8 @@ const UIStrings = {
15
15
  performanceCategoryTitle: 'Performance',
16
16
  /** Title of the speed metrics section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. */
17
17
  metricGroupTitle: 'Metrics',
18
+ /** Title of the insights section of the Performance category. Within this section are various insights to give developers tips on how to improve the performance of their page. */
19
+ insightGroupTitle: 'Insights',
18
20
  /** Title of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */
19
21
  firstPaintImprovementsGroupTitle: 'First Paint Improvements',
20
22
  /** Description of an opportunity sub-section of the Performance category. Within this section are audits with imperative titles that suggest actions the user can take to improve the time of the first initial render of the webpage. */
@@ -308,11 +310,28 @@ const defaultConfig = {
308
310
  'seo/manual/structured-data',
309
311
  'work-during-interaction',
310
312
  'bf-cache',
313
+ 'insights/cls-culprits-insight',
314
+ 'insights/document-latency-insight',
315
+ 'insights/dom-size-insight',
316
+ 'insights/font-display-insight',
317
+ 'insights/forced-reflow-insight',
318
+ 'insights/image-delivery-insight',
319
+ 'insights/interaction-to-next-paint-insight',
320
+ 'insights/lcp-discovery-insight',
321
+ 'insights/lcp-phases-insight',
322
+ 'insights/long-critical-network-tree-insight',
323
+ 'insights/render-blocking-insight',
324
+ 'insights/slow-css-selector-insight',
325
+ 'insights/third-parties-insight',
326
+ 'insights/viewport-insight',
311
327
  ],
312
328
  groups: {
313
329
  'metrics': {
314
330
  title: str_(UIStrings.metricGroupTitle),
315
331
  },
332
+ 'insights': {
333
+ title: str_(UIStrings.insightGroupTitle),
334
+ },
316
335
  'diagnostics': {
317
336
  title: str_(UIStrings.diagnosticsGroupTitle),
318
337
  description: str_(UIStrings.diagnosticsGroupDescription),
@@ -388,6 +407,22 @@ const defaultConfig = {
388
407
  {id: 'speed-index', weight: 10, group: 'metrics', acronym: 'SI'},
389
408
  {id: 'interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP'},
390
409
 
410
+ // Insight audits.
411
+ {id: 'cls-culprits-insight', weight: 0, group: 'hidden'},
412
+ {id: 'document-latency-insight', weight: 0, group: 'hidden'},
413
+ {id: 'dom-size-insight', weight: 0, group: 'hidden'},
414
+ {id: 'font-display-insight', weight: 0, group: 'hidden'},
415
+ {id: 'forced-reflow-insight', weight: 0, group: 'hidden'},
416
+ {id: 'image-delivery-insight', weight: 0, group: 'hidden'},
417
+ {id: 'interaction-to-next-paint-insight', weight: 0, group: 'hidden'},
418
+ {id: 'lcp-discovery-insight', weight: 0, group: 'hidden'},
419
+ {id: 'lcp-phases-insight', weight: 0, group: 'hidden'},
420
+ {id: 'long-critical-network-tree-insight', weight: 0, group: 'hidden'},
421
+ {id: 'render-blocking-insight', weight: 0, group: 'hidden'},
422
+ {id: 'slow-css-selector-insight', weight: 0, group: 'hidden'},
423
+ {id: 'third-parties-insight', weight: 0, group: 'hidden'},
424
+ {id: 'viewport-insight', weight: 0, group: 'hidden'},
425
+
391
426
  // These are our "invisible" metrics. Not displayed, but still in the LHR.
392
427
  {id: 'interactive', weight: 0, group: 'hidden', acronym: 'TTI'},
393
428
  {id: 'max-potential-fid', weight: 0, group: 'hidden'},
@@ -9,6 +9,14 @@ export type TraceElementData = {
9
9
  type?: string;
10
10
  };
11
11
  declare class TraceElements extends BaseGatherer {
12
+ /**
13
+ * @param {LH.Artifacts.TraceEngineResult} traceEngineResult
14
+ * @param {string|undefined} navigationId
15
+ * @return {Promise<Array<{nodeId: number}>>}
16
+ */
17
+ static getTraceEngineElements(traceEngineResult: LH.Artifacts.TraceEngineResult, navigationId: string | undefined): Promise<Array<{
18
+ nodeId: number;
19
+ }>>;
12
20
  /**
13
21
  * We want to a single representative node to represent the shift, so let's pick
14
22
  * the one with the largest impact (size x distance moved).