lighthouse 12.3.0-dev.20250224 → 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.js +1 -1
- 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 -21
- package/shared/localization/locales/ar.json +0 -21
- package/shared/localization/locales/bg.json +0 -21
- package/shared/localization/locales/ca.json +0 -21
- package/shared/localization/locales/cs.json +0 -21
- package/shared/localization/locales/da.json +0 -21
- package/shared/localization/locales/de.json +0 -21
- package/shared/localization/locales/el.json +0 -21
- package/shared/localization/locales/en-GB.json +0 -21
- package/shared/localization/locales/en-US.json +33 -24
- package/shared/localization/locales/en-XA.json +0 -21
- package/shared/localization/locales/en-XL.json +33 -24
- package/shared/localization/locales/es-419.json +0 -21
- package/shared/localization/locales/es.json +0 -21
- package/shared/localization/locales/fi.json +0 -21
- package/shared/localization/locales/fil.json +0 -21
- package/shared/localization/locales/fr.json +0 -21
- package/shared/localization/locales/he.json +0 -21
- package/shared/localization/locales/hi.json +0 -21
- package/shared/localization/locales/hr.json +0 -21
- package/shared/localization/locales/hu.json +0 -21
- package/shared/localization/locales/id.json +0 -21
- package/shared/localization/locales/it.json +0 -21
- package/shared/localization/locales/ja.json +0 -21
- package/shared/localization/locales/ko.json +0 -21
- package/shared/localization/locales/lt.json +0 -21
- package/shared/localization/locales/lv.json +0 -21
- package/shared/localization/locales/nl.json +0 -21
- package/shared/localization/locales/no.json +0 -21
- package/shared/localization/locales/pl.json +0 -21
- package/shared/localization/locales/pt-PT.json +0 -21
- package/shared/localization/locales/pt.json +0 -21
- package/shared/localization/locales/ro.json +0 -21
- package/shared/localization/locales/ru.json +0 -21
- package/shared/localization/locales/sk.json +0 -21
- package/shared/localization/locales/sl.json +0 -21
- package/shared/localization/locales/sr-Latn.json +0 -21
- package/shared/localization/locales/sr.json +0 -21
- package/shared/localization/locales/sv.json +0 -21
- package/shared/localization/locales/ta.json +0 -21
- package/shared/localization/locales/te.json +0 -21
- package/shared/localization/locales/th.json +0 -21
- package/shared/localization/locales/tr.json +0 -21
- package/shared/localization/locales/uk.json +0 -21
- package/shared/localization/locales/vi.json +0 -21
- package/shared/localization/locales/zh-HK.json +0 -21
- package/shared/localization/locales/zh-TW.json +0 -21
- package/shared/localization/locales/zh.json +0 -21
- 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/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
|
|
|
@@ -79,7 +79,7 @@ class LayoutShifts extends Audit {
|
|
|
79
79
|
const items = [];
|
|
80
80
|
const layoutShiftEvents =
|
|
81
81
|
/** @type {import('../lib/trace-engine.js').SaneSyntheticLayoutShift[]} */(
|
|
82
|
-
clusters.flatMap(c => c.events)
|
|
82
|
+
clusters.flatMap(c => c.events).filter(e => !!e.args.data)
|
|
83
83
|
);
|
|
84
84
|
const topLayoutShiftEvents = layoutShiftEvents
|
|
85
85
|
.sort((a, b) => b.args.data.weighted_score_delta - a.args.data.weighted_score_delta)
|
|
@@ -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
|