lighthouse 12.3.0-dev.20250223 → 12.3.0-dev.20250225
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.
- package/core/audits/audit.js +1 -0
- package/core/audits/insights/cls-culprits-insight.d.ts +14 -0
- package/core/audits/insights/cls-culprits-insight.js +97 -12
- package/core/audits/insights/document-latency-insight.js +1 -0
- package/core/audits/insights/dom-size-insight.js +1 -0
- package/core/audits/insights/font-display-insight.js +1 -0
- package/core/audits/insights/image-delivery-insight.js +6 -0
- package/core/audits/insights/interaction-to-next-paint-insight.js +1 -0
- package/core/audits/insights/lcp-discovery-insight.js +1 -0
- package/core/audits/insights/lcp-phases-insight.js +1 -0
- package/core/audits/insights/long-critical-network-tree-insight.js +1 -0
- package/core/audits/insights/render-blocking-insight.js +1 -0
- package/core/audits/insights/third-parties-insight.js +1 -0
- package/core/audits/insights/viewport-insight.js +1 -0
- package/core/audits/layout-shifts.d.ts +0 -1
- package/core/audits/layout-shifts.js +18 -21
- package/core/config/default-config.js +0 -1
- package/core/gather/gatherers/trace-elements.d.ts +2 -2
- package/core/gather/gatherers/trace-elements.js +27 -20
- package/core/lib/bf-cache-strings.d.ts +7 -4
- package/core/lib/bf-cache-strings.js +174 -140
- package/core/lib/cdt/generated/ParsedURL.d.ts +1 -0
- package/core/lib/cdt/generated/ParsedURL.js +16 -4
- package/core/lib/cdt/generated/SourceMap.d.ts +32 -5
- package/core/lib/cdt/generated/SourceMap.js +192 -100
- package/core/lib/deprecations-strings.d.ts +78 -98
- package/core/lib/deprecations-strings.js +23 -41
- package/core/lib/i18n/i18n.d.ts +1 -0
- package/core/lib/i18n/i18n.js +2 -0
- package/dist/report/bundle.esm.js +164 -15
- package/dist/report/flow.js +159 -10
- package/dist/report/standalone.js +158 -9
- package/package.json +3 -3
- package/readme.md +1 -0
- package/report/assets/styles.css +141 -5
- package/report/assets/templates.html +13 -0
- package/report/renderer/components.js +2 -2
- package/report/renderer/details-renderer.js +3 -0
- package/report/renderer/dom.d.ts +12 -1
- package/report/renderer/dom.js +26 -1
- package/report/renderer/performance-category-renderer.d.ts +2 -2
- package/report/renderer/performance-category-renderer.js +58 -23
- package/report/renderer/topbar-features.js +4 -5
- package/shared/localization/locales/ar-XB.json +0 -24
- package/shared/localization/locales/ar.json +0 -24
- package/shared/localization/locales/bg.json +0 -24
- package/shared/localization/locales/ca.json +0 -24
- package/shared/localization/locales/cs.json +0 -24
- package/shared/localization/locales/da.json +0 -24
- package/shared/localization/locales/de.json +0 -24
- package/shared/localization/locales/el.json +0 -24
- package/shared/localization/locales/en-GB.json +0 -24
- package/shared/localization/locales/en-US.json +33 -27
- package/shared/localization/locales/en-XA.json +0 -24
- package/shared/localization/locales/en-XL.json +33 -27
- package/shared/localization/locales/es-419.json +0 -24
- package/shared/localization/locales/es.json +0 -24
- package/shared/localization/locales/fi.json +0 -24
- package/shared/localization/locales/fil.json +0 -24
- package/shared/localization/locales/fr.json +0 -24
- package/shared/localization/locales/he.json +0 -24
- package/shared/localization/locales/hi.json +0 -24
- package/shared/localization/locales/hr.json +0 -24
- package/shared/localization/locales/hu.json +0 -24
- package/shared/localization/locales/id.json +0 -24
- package/shared/localization/locales/it.json +0 -24
- package/shared/localization/locales/ja.json +0 -24
- package/shared/localization/locales/ko.json +0 -24
- package/shared/localization/locales/lt.json +0 -24
- package/shared/localization/locales/lv.json +0 -24
- package/shared/localization/locales/nl.json +0 -24
- package/shared/localization/locales/no.json +0 -24
- package/shared/localization/locales/pl.json +0 -24
- package/shared/localization/locales/pt-PT.json +0 -24
- package/shared/localization/locales/pt.json +0 -24
- package/shared/localization/locales/ro.json +0 -24
- package/shared/localization/locales/ru.json +0 -24
- package/shared/localization/locales/sk.json +0 -24
- package/shared/localization/locales/sl.json +0 -24
- package/shared/localization/locales/sr-Latn.json +0 -24
- package/shared/localization/locales/sr.json +0 -24
- package/shared/localization/locales/sv.json +0 -24
- package/shared/localization/locales/ta.json +0 -24
- package/shared/localization/locales/te.json +0 -24
- package/shared/localization/locales/th.json +0 -24
- package/shared/localization/locales/tr.json +0 -24
- package/shared/localization/locales/uk.json +0 -24
- package/shared/localization/locales/vi.json +0 -24
- package/shared/localization/locales/zh-HK.json +0 -24
- package/shared/localization/locales/zh-TW.json +0 -24
- package/shared/localization/locales/zh.json +0 -24
- package/types/artifacts.d.ts +1 -2
- package/types/audit.d.ts +2 -0
- package/types/lhr/audit-details.d.ts +5 -1
- package/types/lhr/audit-result.d.ts +2 -0
- package/core/gather/gatherers/root-causes.d.ts +0 -19
- package/core/gather/gatherers/root-causes.js +0 -144
package/core/audits/audit.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export default CLSCulpritsInsight;
|
|
2
|
+
export type SubItem = {
|
|
3
|
+
extra?: LH.Audit.Details.NodeValue | LH.Audit.Details.UrlValue;
|
|
4
|
+
cause: LH.IcuMessage;
|
|
5
|
+
};
|
|
2
6
|
declare class CLSCulpritsInsight extends Audit {
|
|
7
|
+
/**
|
|
8
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/CLSCulprits.js').CLSCulpritsInsightModel} insight
|
|
9
|
+
* @param {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift} event
|
|
10
|
+
* @param {LH.Artifacts.TraceElement[]} TraceElements
|
|
11
|
+
* @return {LH.Audit.Details.TableSubItems|undefined}
|
|
12
|
+
*/
|
|
13
|
+
static getCulpritSubItems(insight: import("@paulirish/trace_engine/models/trace/insights/CLSCulprits.js").CLSCulpritsInsightModel, event: import("../../lib/trace-engine.js").SaneSyntheticLayoutShift, TraceElements: LH.Artifacts.TraceElement[]): LH.Audit.Details.TableSubItems | undefined;
|
|
3
14
|
/**
|
|
4
15
|
* @param {LH.Artifacts} artifacts
|
|
5
16
|
* @param {LH.Audit.Context} context
|
|
@@ -7,5 +18,8 @@ declare class CLSCulpritsInsight extends Audit {
|
|
|
7
18
|
*/
|
|
8
19
|
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
9
20
|
}
|
|
21
|
+
export namespace UIStrings {
|
|
22
|
+
let columnScore: string;
|
|
23
|
+
}
|
|
10
24
|
import { Audit } from '../audit.js';
|
|
11
25
|
//# sourceMappingURL=cls-culprits-insight.d.ts.map
|
|
@@ -1,19 +1,32 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */ // TODO: remove once implemented.
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @license
|
|
5
3
|
* Copyright 2025 Google LLC
|
|
6
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
|
-
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/CLSCulprits.js';
|
|
7
|
+
import {UIStrings as InsightUIStrings} from '@paulirish/trace_engine/models/trace/insights/CLSCulprits.js';
|
|
10
8
|
|
|
11
9
|
import {Audit} from '../audit.js';
|
|
12
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
11
|
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
12
|
+
import TraceElements from '../../gather/gatherers/trace-elements.js';
|
|
13
|
+
import {CumulativeLayoutShift} from '../../computed/metrics/cumulative-layout-shift.js';
|
|
14
|
+
|
|
15
|
+
const MAX_LAYOUT_SHIFTS_PER_CLUSTER = 5;
|
|
16
|
+
|
|
17
|
+
/** @typedef {{extra?: LH.Audit.Details.NodeValue | LH.Audit.Details.UrlValue, cause: LH.IcuMessage}} SubItem */
|
|
14
18
|
|
|
15
19
|
// eslint-disable-next-line max-len
|
|
16
|
-
const
|
|
20
|
+
const insightStr_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js', InsightUIStrings);
|
|
21
|
+
|
|
22
|
+
/* eslint-disable max-len */
|
|
23
|
+
const UIStrings = {
|
|
24
|
+
/** Label for a column in a data table; entries in this column will be a number representing how large the layout shift was. */
|
|
25
|
+
columnScore: 'Layout shift score',
|
|
26
|
+
};
|
|
27
|
+
/* eslint-enable max-len */
|
|
28
|
+
|
|
29
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
17
30
|
|
|
18
31
|
class CLSCulpritsInsight extends Audit {
|
|
19
32
|
/**
|
|
@@ -22,31 +35,103 @@ class CLSCulpritsInsight extends Audit {
|
|
|
22
35
|
static get meta() {
|
|
23
36
|
return {
|
|
24
37
|
id: 'cls-culprits-insight',
|
|
25
|
-
title:
|
|
26
|
-
failureTitle:
|
|
27
|
-
description:
|
|
38
|
+
title: insightStr_(InsightUIStrings.title),
|
|
39
|
+
failureTitle: insightStr_(InsightUIStrings.title),
|
|
40
|
+
description: insightStr_(InsightUIStrings.description),
|
|
28
41
|
guidanceLevel: 3,
|
|
29
42
|
requiredArtifacts: ['traces', 'TraceElements'],
|
|
43
|
+
replacesAudits: ['layout-shifts', 'non-composited-animations', 'unsized-images'],
|
|
30
44
|
};
|
|
31
45
|
}
|
|
32
46
|
|
|
47
|
+
/**
|
|
48
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/CLSCulprits.js').CLSCulpritsInsightModel} insight
|
|
49
|
+
* @param {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift} event
|
|
50
|
+
* @param {LH.Artifacts.TraceElement[]} TraceElements
|
|
51
|
+
* @return {LH.Audit.Details.TableSubItems|undefined}
|
|
52
|
+
*/
|
|
53
|
+
static getCulpritSubItems(insight, event, TraceElements) {
|
|
54
|
+
const culprits = insight.shifts.get(event);
|
|
55
|
+
if (!culprits) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @type {SubItem[]} */
|
|
60
|
+
const subItems = [];
|
|
61
|
+
for (const backendNodeId of culprits.unsizedImages) {
|
|
62
|
+
subItems.push({
|
|
63
|
+
extra: makeNodeItemForNodeId(TraceElements, backendNodeId),
|
|
64
|
+
cause: insightStr_(InsightUIStrings.unsizedImages),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
for (const request of culprits.fontRequests) {
|
|
68
|
+
const url = request.args.data.url;
|
|
69
|
+
subItems.push({
|
|
70
|
+
extra: {type: 'url', value: url},
|
|
71
|
+
cause: insightStr_(InsightUIStrings.fontRequest),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (culprits.iframeIds.length) {
|
|
75
|
+
subItems.push({
|
|
76
|
+
cause: insightStr_(InsightUIStrings.injectedIframe),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (subItems.length) {
|
|
81
|
+
return {type: 'subitems', items: subItems};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
33
85
|
/**
|
|
34
86
|
* @param {LH.Artifacts} artifacts
|
|
35
87
|
* @param {LH.Audit.Context} context
|
|
36
88
|
* @return {Promise<LH.Audit.Product>}
|
|
37
89
|
*/
|
|
38
90
|
static async audit(artifacts, context) {
|
|
39
|
-
// TODO: implement.
|
|
40
91
|
return adaptInsightToAuditProduct(artifacts, context, 'CLSCulprits', (insight) => {
|
|
41
92
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
42
93
|
const headings = [
|
|
94
|
+
/* eslint-disable max-len */
|
|
95
|
+
{key: 'node', valueType: 'node', subItemsHeading: {key: 'extra'}, label: insightStr_(i18n.UIStrings.columnElement)},
|
|
96
|
+
{key: 'score', valueType: 'numeric', subItemsHeading: {key: 'cause', valueType: 'text'}, granularity: 0.001, label: str_(UIStrings.columnScore)},
|
|
97
|
+
/* eslint-enable max-len */
|
|
43
98
|
];
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
99
|
+
|
|
100
|
+
const tables = insight.clusters.map(cluster => {
|
|
101
|
+
const events =
|
|
102
|
+
/** @type {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift[]} */ (
|
|
103
|
+
cluster.events.filter(e => !!e.args.data)
|
|
104
|
+
).sort((a, b) => b.args.data.weighted_score_delta - a.args.data.weighted_score_delta)
|
|
105
|
+
.slice(0, MAX_LAYOUT_SHIFTS_PER_CLUSTER);
|
|
106
|
+
const impactByNodeId = CumulativeLayoutShift.getImpactByNodeId(events.map(e => ({
|
|
107
|
+
impactedNodes: e.args.data.impacted_nodes,
|
|
108
|
+
ts: e.ts,
|
|
109
|
+
isMainFrame: e.args.data.is_main_frame,
|
|
110
|
+
weightedScore: e.args.data.weighted_score_delta,
|
|
111
|
+
event: /** @type {any} */ (e),
|
|
112
|
+
})));
|
|
113
|
+
|
|
114
|
+
/** @type {LH.Audit.Details.Table['items']} */
|
|
115
|
+
const items = events.map(event => {
|
|
116
|
+
const biggestImpactNodeId = TraceElements.getBiggestImpactNodeForShiftEvent(
|
|
117
|
+
event.args.data.impacted_nodes || [], impactByNodeId, event);
|
|
118
|
+
return {
|
|
119
|
+
node: makeNodeItemForNodeId(artifacts.TraceElements, biggestImpactNodeId),
|
|
120
|
+
score: event.args.data?.weighted_score_delta,
|
|
121
|
+
subItems: this.getCulpritSubItems(insight, event, artifacts.TraceElements),
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
items.unshift({
|
|
125
|
+
node: {type: 'text', value: insightStr_(i18n.UIStrings.total)},
|
|
126
|
+
score: cluster.clusterCumulativeScore,
|
|
127
|
+
});
|
|
128
|
+
return Audit.makeTableDetails(headings, items);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return Audit.makeListDetails(tables);
|
|
48
132
|
});
|
|
49
133
|
}
|
|
50
134
|
}
|
|
51
135
|
|
|
52
136
|
export default CLSCulpritsInsight;
|
|
137
|
+
export {UIStrings};
|
|
@@ -25,6 +25,12 @@ class ImageDeliveryInsight extends Audit {
|
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
27
|
requiredArtifacts: ['traces', 'TraceElements'],
|
|
28
|
+
replacesAudits: [
|
|
29
|
+
'modern-image-formats',
|
|
30
|
+
'uses-optimized-images',
|
|
31
|
+
'efficient-animated-content',
|
|
32
|
+
'uses-responsive-images',
|
|
33
|
+
],
|
|
28
34
|
};
|
|
29
35
|
}
|
|
30
36
|
|
|
@@ -26,7 +26,6 @@ export namespace UIStrings {
|
|
|
26
26
|
let rootCauseUnsizedMedia: string;
|
|
27
27
|
let rootCauseFontChanges: string;
|
|
28
28
|
let rootCauseInjectedIframe: string;
|
|
29
|
-
let rootCauseRenderBlockingRequest: string;
|
|
30
29
|
let displayValueShiftsFound: string;
|
|
31
30
|
}
|
|
32
31
|
import { Audit } from './audit.js';
|
|
@@ -29,8 +29,6 @@ const UIStrings = {
|
|
|
29
29
|
rootCauseFontChanges: 'Web font loaded',
|
|
30
30
|
/** A possible reason why that the layout shift occured. */
|
|
31
31
|
rootCauseInjectedIframe: 'Injected iframe',
|
|
32
|
-
/** A possible reason why that the layout shift occured. */
|
|
33
|
-
rootCauseRenderBlockingRequest: 'A late network request adjusted the page layout',
|
|
34
32
|
/** Label shown per-audit to show how many layout shifts are present. The `{# shifts found}` placeholder will be replaced with the number of layout shifts. */
|
|
35
33
|
displayValueShiftsFound: `{shiftCount, plural, =1 {1 layout shift found} other {# layout shifts found}}`,
|
|
36
34
|
};
|
|
@@ -49,7 +47,7 @@ class LayoutShifts extends Audit {
|
|
|
49
47
|
description: str_(UIStrings.description),
|
|
50
48
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
51
49
|
guidanceLevel: 2,
|
|
52
|
-
requiredArtifacts: ['traces', '
|
|
50
|
+
requiredArtifacts: ['traces', 'TraceElements'],
|
|
53
51
|
};
|
|
54
52
|
}
|
|
55
53
|
|
|
@@ -67,11 +65,21 @@ class LayoutShifts extends Audit {
|
|
|
67
65
|
const traceElements = artifacts.TraceElements
|
|
68
66
|
.filter(element => element.traceEventType === 'layout-shift');
|
|
69
67
|
|
|
68
|
+
/** @type {LH.Artifacts.TraceEngineRootCauses} */
|
|
69
|
+
const allRootCauses = {
|
|
70
|
+
layoutShifts: new Map(),
|
|
71
|
+
};
|
|
72
|
+
for (const insightSet of traceEngineResult.insights.values()) {
|
|
73
|
+
for (const [shift, reasons] of insightSet.model.CLSCulprits.shifts) {
|
|
74
|
+
allRootCauses.layoutShifts.set(shift, reasons);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
70
78
|
/** @type {Item[]} */
|
|
71
79
|
const items = [];
|
|
72
80
|
const layoutShiftEvents =
|
|
73
81
|
/** @type {import('../lib/trace-engine.js').SaneSyntheticLayoutShift[]} */(
|
|
74
|
-
clusters.flatMap(c => c.events)
|
|
82
|
+
clusters.flatMap(c => c.events).filter(e => !!e.args.data)
|
|
75
83
|
);
|
|
76
84
|
const topLayoutShiftEvents = layoutShiftEvents
|
|
77
85
|
.sort((a, b) => b.args.data.weighted_score_delta - a.args.data.weighted_score_delta)
|
|
@@ -82,41 +90,30 @@ class LayoutShifts extends Audit {
|
|
|
82
90
|
const biggestImpactElement = traceElements.find(t => t.nodeId === biggestImpactNodeId);
|
|
83
91
|
|
|
84
92
|
// Turn root causes into sub-items.
|
|
85
|
-
const
|
|
86
|
-
const rootCauses = artifacts.RootCauses.layoutShifts[index];
|
|
93
|
+
const rootCauses = allRootCauses.layoutShifts.get(event);
|
|
87
94
|
/** @type {SubItem[]} */
|
|
88
95
|
const subItems = [];
|
|
89
96
|
if (rootCauses) {
|
|
90
|
-
for (const
|
|
97
|
+
for (const backendNodeId of rootCauses.unsizedImages) {
|
|
91
98
|
const element = artifacts.TraceElements.find(
|
|
92
|
-
t => t.traceEventType === '
|
|
99
|
+
t => t.traceEventType === 'trace-engine' && t.nodeId === backendNodeId);
|
|
93
100
|
subItems.push({
|
|
94
101
|
extra: element ? Audit.makeNodeItem(element.node) : undefined,
|
|
95
102
|
cause: str_(UIStrings.rootCauseUnsizedMedia),
|
|
96
103
|
});
|
|
97
104
|
}
|
|
98
|
-
for (const
|
|
99
|
-
const url =
|
|
105
|
+
for (const request of rootCauses.fontRequests) {
|
|
106
|
+
const url = request.args.data.url;
|
|
100
107
|
subItems.push({
|
|
101
108
|
extra: {type: 'url', value: url},
|
|
102
109
|
cause: str_(UIStrings.rootCauseFontChanges),
|
|
103
110
|
});
|
|
104
111
|
}
|
|
105
|
-
|
|
106
|
-
const element = artifacts.TraceElements.find(
|
|
107
|
-
t => t.traceEventType === 'layout-shift' && t.nodeId === cause.iframe.backendNodeId);
|
|
112
|
+
if (rootCauses.iframeIds.length) {
|
|
108
113
|
subItems.push({
|
|
109
|
-
extra: element ? Audit.makeNodeItem(element.node) : undefined,
|
|
110
114
|
cause: str_(UIStrings.rootCauseInjectedIframe),
|
|
111
115
|
});
|
|
112
116
|
}
|
|
113
|
-
for (const cause of rootCauses.renderBlockingRequests) {
|
|
114
|
-
const url = cause.request.args.data.url;
|
|
115
|
-
subItems.push({
|
|
116
|
-
extra: {type: 'url', value: url},
|
|
117
|
-
cause: str_(UIStrings.rootCauseRenderBlockingRequest),
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
117
|
}
|
|
121
118
|
|
|
122
119
|
items.push({
|
|
@@ -109,7 +109,6 @@ const defaultConfig = {
|
|
|
109
109
|
// Artifacts which can be depended on come first.
|
|
110
110
|
{id: 'DevtoolsLog', gatherer: 'devtools-log'},
|
|
111
111
|
{id: 'Trace', gatherer: 'trace'},
|
|
112
|
-
{id: 'RootCauses', gatherer: 'root-causes'},
|
|
113
112
|
|
|
114
113
|
{id: 'Accessibility', gatherer: 'accessibility'},
|
|
115
114
|
{id: 'AnchorElements', gatherer: 'anchor-elements'},
|
|
@@ -56,8 +56,8 @@ declare class TraceElements extends BaseGatherer {
|
|
|
56
56
|
nodeId: number;
|
|
57
57
|
type: string;
|
|
58
58
|
} | undefined>;
|
|
59
|
-
/** @type {LH.Gatherer.GathererMeta<'Trace'
|
|
60
|
-
meta: LH.Gatherer.GathererMeta<"Trace"
|
|
59
|
+
/** @type {LH.Gatherer.GathererMeta<'Trace'>} */
|
|
60
|
+
meta: LH.Gatherer.GathererMeta<"Trace">;
|
|
61
61
|
/** @type {Map<string, string>} */
|
|
62
62
|
animationIdToName: Map<string, string>;
|
|
63
63
|
/** @param {LH.Crdp.Animation.AnimationStartedEvent} args */
|
|
@@ -23,7 +23,6 @@ import {LighthouseError} from '../../lib/lh-error.js';
|
|
|
23
23
|
import {Responsiveness} from '../../computed/metrics/responsiveness.js';
|
|
24
24
|
import {CumulativeLayoutShift} from '../../computed/metrics/cumulative-layout-shift.js';
|
|
25
25
|
import {ExecutionContext} from '../driver/execution-context.js';
|
|
26
|
-
import RootCauses from './root-causes.js';
|
|
27
26
|
import {TraceEngineResult} from '../../computed/trace-engine-result.js';
|
|
28
27
|
|
|
29
28
|
/** @typedef {{nodeId: number, animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[], type?: string}} TraceElementData */
|
|
@@ -46,10 +45,10 @@ function getNodeDetailsData() {
|
|
|
46
45
|
/* c8 ignore stop */
|
|
47
46
|
|
|
48
47
|
class TraceElements extends BaseGatherer {
|
|
49
|
-
/** @type {LH.Gatherer.GathererMeta<'Trace'
|
|
48
|
+
/** @type {LH.Gatherer.GathererMeta<'Trace'>} */
|
|
50
49
|
meta = {
|
|
51
50
|
supportedModes: ['timespan', 'navigation'],
|
|
52
|
-
dependencies: {Trace: Trace.symbol
|
|
51
|
+
dependencies: {Trace: Trace.symbol},
|
|
53
52
|
};
|
|
54
53
|
|
|
55
54
|
/** @type {Map<string, string>} */
|
|
@@ -103,13 +102,23 @@ class TraceElements extends BaseGatherer {
|
|
|
103
102
|
seen.add(obj);
|
|
104
103
|
|
|
105
104
|
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
if (obj instanceof Map) {
|
|
106
|
+
for (const [key, val] of obj) {
|
|
107
|
+
if (typeof val === 'object') {
|
|
108
|
+
recursiveObjectEnumerate(val, cb, seen);
|
|
109
|
+
} else {
|
|
110
|
+
cb(val, key);
|
|
111
|
+
}
|
|
111
112
|
}
|
|
112
|
-
}
|
|
113
|
+
} else {
|
|
114
|
+
Object.keys(obj).forEach(key => {
|
|
115
|
+
if (typeof obj[key] === 'object') {
|
|
116
|
+
recursiveObjectEnumerate(obj[key], cb, seen);
|
|
117
|
+
} else {
|
|
118
|
+
cb(obj[key], key);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
113
122
|
} else if (Array.isArray(obj)) {
|
|
114
123
|
obj.forEach(item => {
|
|
115
124
|
if (typeof item === 'object' || Array.isArray(item)) {
|
|
@@ -121,12 +130,18 @@ class TraceElements extends BaseGatherer {
|
|
|
121
130
|
|
|
122
131
|
/** @type {number[]} */
|
|
123
132
|
const nodeIds = [];
|
|
124
|
-
recursiveObjectEnumerate(insightSet.model, (
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
recursiveObjectEnumerate(insightSet.model, (val, key) => {
|
|
134
|
+
const keys = ['nodeId', 'node_id'];
|
|
135
|
+
if (typeof val === 'number' && keys.includes(key)) {
|
|
136
|
+
nodeIds.push(val);
|
|
127
137
|
}
|
|
128
138
|
}, new Set());
|
|
129
139
|
|
|
140
|
+
// TODO: would be better if unsizedImages was `Array<{nodeId}>`.
|
|
141
|
+
for (const shift of insightSet.model.CLSCulprits.shifts.values()) {
|
|
142
|
+
nodeIds.push(...shift.unsizedImages);
|
|
143
|
+
}
|
|
144
|
+
|
|
130
145
|
return [...new Set(nodeIds)].map(id => ({nodeId: id}));
|
|
131
146
|
}
|
|
132
147
|
|
|
@@ -212,14 +227,6 @@ class TraceElements extends BaseGatherer {
|
|
|
212
227
|
nodeIds.push(biggestImpactedNodeId);
|
|
213
228
|
}
|
|
214
229
|
|
|
215
|
-
const index = layoutShiftEvents.indexOf(event);
|
|
216
|
-
const shiftRootCauses = rootCauses.layoutShifts[index];
|
|
217
|
-
if (shiftRootCauses) {
|
|
218
|
-
for (const cause of shiftRootCauses.unsizedMedia) {
|
|
219
|
-
nodeIds.push(cause.node.backendNodeId);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
230
|
return nodeIds.map(nodeId => ({nodeId}));
|
|
224
231
|
});
|
|
225
232
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/** @type {Record<string, {name: LH.IcuMessage} | undefined>} */
|
|
1
|
+
/** @type {Record<string, {name: LH.IcuMessage|string} | undefined>} */
|
|
2
2
|
export const NotRestoredReasonDescription: Record<string, {
|
|
3
|
-
name: LH.IcuMessage;
|
|
3
|
+
name: LH.IcuMessage | string;
|
|
4
4
|
} | undefined>;
|
|
5
5
|
export namespace UIStrings {
|
|
6
6
|
let notMainFrame: string;
|
|
@@ -77,7 +77,6 @@ export namespace UIStrings {
|
|
|
77
77
|
let printing: string;
|
|
78
78
|
let webDatabase: string;
|
|
79
79
|
let pictureInPicture: string;
|
|
80
|
-
let portal: string;
|
|
81
80
|
let speechRecognizer: string;
|
|
82
81
|
let idleManager: string;
|
|
83
82
|
let paymentManager: string;
|
|
@@ -87,6 +86,7 @@ export namespace UIStrings {
|
|
|
87
86
|
let outstandingNetworkRequestDirectSocket: string;
|
|
88
87
|
let injectedJavascript: string;
|
|
89
88
|
let injectedStyleSheet: string;
|
|
89
|
+
let contentDiscarded: string;
|
|
90
90
|
let contentSecurityHandler: string;
|
|
91
91
|
let contentWebAuthenticationAPI: string;
|
|
92
92
|
let contentFileChooser: string;
|
|
@@ -117,8 +117,11 @@ export namespace UIStrings {
|
|
|
117
117
|
let errorDocument: string;
|
|
118
118
|
let fencedFramesEmbedder: string;
|
|
119
119
|
let keepaliveRequest: string;
|
|
120
|
-
let
|
|
120
|
+
let jsNetworkRequestReceivedCacheControlNoStoreResource: string;
|
|
121
121
|
let indexedDBEvent: string;
|
|
122
122
|
let cookieDisabled: string;
|
|
123
|
+
let webRTCSticky: string;
|
|
124
|
+
let webTransportSticky: string;
|
|
125
|
+
let webSocketSticky: string;
|
|
123
126
|
}
|
|
124
127
|
//# sourceMappingURL=bf-cache-strings.d.ts.map
|