lighthouse 12.4.0 → 12.5.0-dev.20250325
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 +3 -1
- package/core/audits/bootup-time.js +1 -1
- package/core/audits/byte-efficiency/duplicated-javascript.js +1 -1
- package/core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/core/audits/byte-efficiency/legacy-javascript.d.ts +0 -65
- package/core/audits/byte-efficiency/legacy-javascript.js +11 -363
- package/core/audits/byte-efficiency/modern-image-formats.js +1 -1
- package/core/audits/byte-efficiency/offscreen-images.js +4 -3
- package/core/audits/byte-efficiency/render-blocking-resources.js +6 -3
- package/core/audits/byte-efficiency/unminified-css.js +2 -1
- package/core/audits/byte-efficiency/unminified-javascript.js +2 -1
- package/core/audits/byte-efficiency/unused-css-rules.js +1 -1
- package/core/audits/byte-efficiency/unused-javascript.js +2 -2
- package/core/audits/byte-efficiency/uses-long-cache-ttl.js +1 -1
- package/core/audits/byte-efficiency/uses-optimized-images.js +1 -1
- package/core/audits/byte-efficiency/uses-responsive-images.js +1 -1
- package/core/audits/byte-efficiency/uses-text-compression.js +2 -1
- package/core/audits/critical-request-chains.js +5 -3
- package/core/audits/dobetterweb/dom-size.js +1 -1
- package/core/audits/dobetterweb/uses-http2.js +1 -1
- package/core/audits/insights/cls-culprits-insight.js +1 -1
- package/core/audits/insights/document-latency-insight.js +1 -1
- package/core/audits/insights/dom-size-insight.js +1 -1
- package/core/audits/insights/{long-critical-network-tree-insight.d.ts → duplicated-javascript-insight.d.ts} +3 -3
- package/core/audits/insights/duplicated-javascript-insight.js +54 -0
- package/core/audits/insights/font-display-insight.js +8 -7
- package/core/audits/insights/forced-reflow-insight.d.ts +10 -0
- package/core/audits/insights/forced-reflow-insight.js +64 -12
- package/core/audits/insights/image-delivery-insight.js +9 -10
- package/core/audits/insights/insight-audit.js +9 -4
- package/core/audits/insights/interaction-to-next-paint-insight.js +1 -1
- package/core/audits/insights/lcp-discovery-insight.js +1 -1
- package/core/audits/insights/lcp-phases-insight.js +1 -1
- package/core/audits/insights/network-dependency-tree-insight.d.ts +11 -0
- package/core/audits/insights/{long-critical-network-tree-insight.js → network-dependency-tree-insight.js} +7 -7
- package/core/audits/insights/render-blocking-insight.js +1 -1
- package/core/audits/insights/slow-css-selector-insight.js +1 -1
- package/core/audits/insights/third-parties-insight.js +1 -1
- package/core/audits/insights/use-cache-insight.d.ts +11 -0
- package/core/audits/insights/use-cache-insight.js +61 -0
- package/core/audits/insights/viewport-insight.js +1 -1
- package/core/audits/largest-contentful-paint-element.js +7 -3
- package/core/audits/layout-shifts.js +5 -2
- package/core/audits/lcp-lazy-loaded.js +1 -1
- package/core/audits/long-tasks.js +6 -4
- package/core/audits/mainthread-work-breakdown.js +1 -1
- package/core/audits/metrics/first-contentful-paint.js +4 -2
- package/core/audits/metrics/interactive.js +6 -3
- package/core/audits/metrics/largest-contentful-paint.js +7 -3
- package/core/audits/metrics/max-potential-fid.js +6 -3
- package/core/audits/metrics/speed-index.js +6 -3
- package/core/audits/metrics/total-blocking-time.js +6 -3
- package/core/audits/metrics.js +4 -3
- package/core/audits/predictive-perf.js +4 -3
- package/core/audits/prioritize-lcp-image.js +5 -3
- package/core/audits/redirects.js +4 -2
- package/core/audits/script-treemap-data.js +8 -4
- package/core/audits/third-party-facades.js +1 -1
- package/core/audits/third-party-summary.js +1 -1
- package/core/audits/uses-rel-preconnect.js +7 -5
- package/core/audits/uses-rel-preload.js +5 -3
- package/core/computed/computed-artifact.d.ts +5 -1
- package/core/computed/computed-artifact.js +23 -2
- package/core/computed/critical-request-chains.d.ts +5 -1
- package/core/computed/critical-request-chains.js +4 -4
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
- package/core/computed/metrics/first-contentful-paint.js +1 -1
- package/core/computed/metrics/interactive.js +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.js +1 -1
- package/core/computed/metrics/lantern-interactive.js +1 -1
- package/core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/core/computed/metrics/lantern-max-potential-fid.js +1 -1
- package/core/computed/metrics/lantern-metric.js +1 -1
- package/core/computed/metrics/lantern-speed-index.js +1 -1
- package/core/computed/metrics/lantern-total-blocking-time.js +1 -1
- package/core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
- package/core/computed/metrics/largest-contentful-paint.js +1 -1
- package/core/computed/metrics/lcp-breakdown.js +1 -1
- package/core/computed/metrics/max-potential-fid.js +1 -1
- package/core/computed/metrics/metric.js +2 -0
- package/core/computed/metrics/speed-index.js +1 -1
- package/core/computed/metrics/time-to-first-byte.js +1 -1
- package/core/computed/metrics/timing-summary.d.ts +5 -2
- package/core/computed/metrics/timing-summary.js +8 -4
- package/core/computed/metrics/total-blocking-time.js +1 -1
- package/core/computed/module-duplication.d.ts +1 -1
- package/core/computed/navigation-insights.d.ts +11 -3
- package/core/computed/navigation-insights.js +7 -4
- package/core/computed/page-dependency-graph.d.ts +7 -3
- package/core/computed/page-dependency-graph.js +6 -5
- package/core/computed/tbt-impact-tasks.js +1 -1
- package/core/computed/trace-engine-result.d.ts +36 -2
- package/core/computed/trace-engine-result.js +119 -25
- package/core/computed/unused-javascript-summary.d.ts +2 -2
- package/core/computed/unused-javascript-summary.js +1 -1
- package/core/config/default-config.js +19 -15
- package/core/config/experimental-config.js +19 -0
- package/core/gather/gatherers/source-maps.d.ts +1 -0
- package/core/gather/gatherers/source-maps.js +3 -0
- package/core/gather/gatherers/trace-elements.d.ts +4 -4
- package/core/gather/gatherers/trace-elements.js +8 -4
- package/core/gather/gatherers/trace.js +5 -0
- package/core/lib/bf-cache-strings.d.ts +0 -122
- package/core/lib/bf-cache-strings.js +1 -2
- package/core/lib/deprecation-description.js +2 -1
- package/core/lib/legacy-javascript/legacy-javascript.d.ts +29 -0
- package/core/lib/legacy-javascript/legacy-javascript.js +351 -0
- package/core/lib/legacy-javascript/polyfill-graph-data.json +93 -0
- package/core/lib/legacy-javascript/polyfill-module-data.json +623 -0
- package/core/lib/trace-engine.d.ts +6 -1
- package/core/lib/trace-engine.js +1 -2
- package/package.json +10 -8
- package/shared/localization/locales/ar-XB.json +783 -513
- package/shared/localization/locales/ar.json +783 -513
- package/shared/localization/locales/bg.json +933 -663
- package/shared/localization/locales/ca.json +925 -655
- package/shared/localization/locales/cs.json +926 -656
- package/shared/localization/locales/da.json +926 -656
- package/shared/localization/locales/de.json +803 -533
- package/shared/localization/locales/el.json +928 -658
- package/shared/localization/locales/en-GB.json +929 -659
- package/shared/localization/locales/en-US.json +593 -551
- package/shared/localization/locales/en-XA.json +28 -508
- package/shared/localization/locales/en-XL.json +593 -551
- package/shared/localization/locales/es-419.json +928 -658
- package/shared/localization/locales/es.json +787 -517
- package/shared/localization/locales/fi.json +925 -655
- package/shared/localization/locales/fil.json +929 -659
- package/shared/localization/locales/fr.json +927 -657
- package/shared/localization/locales/he.json +795 -528
- package/shared/localization/locales/hi.json +798 -528
- package/shared/localization/locales/hr.json +929 -659
- package/shared/localization/locales/hu.json +926 -656
- package/shared/localization/locales/id.json +926 -656
- package/shared/localization/locales/it.json +930 -660
- package/shared/localization/locales/ja.json +927 -657
- package/shared/localization/locales/ko.json +936 -666
- package/shared/localization/locales/lt.json +933 -663
- package/shared/localization/locales/lv.json +809 -539
- package/shared/localization/locales/nl.json +925 -655
- package/shared/localization/locales/no.json +928 -658
- package/shared/localization/locales/pl.json +927 -657
- package/shared/localization/locales/pt-PT.json +841 -571
- package/shared/localization/locales/pt.json +841 -571
- package/shared/localization/locales/ro.json +925 -655
- package/shared/localization/locales/ru.json +935 -668
- package/shared/localization/locales/sk.json +925 -655
- package/shared/localization/locales/sl.json +927 -657
- package/shared/localization/locales/sr-Latn.json +925 -655
- package/shared/localization/locales/sr.json +925 -655
- package/shared/localization/locales/sv.json +936 -666
- package/shared/localization/locales/ta.json +935 -668
- package/shared/localization/locales/te.json +785 -515
- package/shared/localization/locales/th.json +813 -543
- package/shared/localization/locales/tr.json +927 -657
- package/shared/localization/locales/uk.json +795 -525
- package/shared/localization/locales/vi.json +929 -659
- package/shared/localization/locales/zh-HK.json +926 -656
- package/shared/localization/locales/zh-TW.json +784 -514
- package/shared/localization/locales/zh.json +926 -656
- package/tsconfig.json +2 -1
- package/types/artifacts.d.ts +2 -1
- package/core/audits/byte-efficiency/polyfill-graph-data.json +0 -53
|
@@ -69,7 +69,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
|
|
|
69
69
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
70
70
|
guidanceLevel: 1,
|
|
71
71
|
requiredArtifacts: ['JsUsage', 'Scripts', 'SourceMaps', 'GatherContext',
|
|
72
|
-
'devtoolsLogs', 'traces', 'URL'],
|
|
72
|
+
'devtoolsLogs', 'traces', 'URL', 'SourceMaps'],
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -94,7 +94,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
|
|
|
94
94
|
const script = artifacts.Scripts.find(s => s.scriptId === scriptId);
|
|
95
95
|
if (!script) continue; // This should never happen.
|
|
96
96
|
|
|
97
|
-
const bundle = bundles.find(b => b.script.scriptId === scriptId);
|
|
97
|
+
const bundle = bundles.find(b => b.script.scriptId === scriptId) ?? null;
|
|
98
98
|
const unusedJsSummary =
|
|
99
99
|
await UnusedJavascriptSummary.request({scriptId, scriptCoverage, bundle}, context);
|
|
100
100
|
if (unusedJsSummary.wastedBytes === 0 || unusedJsSummary.totalBytes === 0) continue;
|
|
@@ -46,7 +46,7 @@ class CacheHeaders extends Audit {
|
|
|
46
46
|
description: str_(UIStrings.description),
|
|
47
47
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
48
48
|
guidanceLevel: 3,
|
|
49
|
-
requiredArtifacts: ['devtoolsLogs'],
|
|
49
|
+
requiredArtifacts: ['devtoolsLogs', 'SourceMaps'],
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -37,7 +37,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
|
|
|
37
37
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
38
38
|
guidanceLevel: 2,
|
|
39
39
|
requiredArtifacts: ['OptimizedImages', 'ImageElements', 'GatherContext', 'devtoolsLogs',
|
|
40
|
-
'traces', 'URL'],
|
|
40
|
+
'traces', 'URL', 'SourceMaps'],
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -48,7 +48,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
|
|
|
48
48
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
49
49
|
guidanceLevel: 2,
|
|
50
50
|
requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext',
|
|
51
|
-
'devtoolsLogs', 'traces', 'URL'],
|
|
51
|
+
'devtoolsLogs', 'traces', 'URL', 'SourceMaps'],
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -38,7 +38,8 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
|
|
|
38
38
|
description: str_(UIStrings.description),
|
|
39
39
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
40
40
|
guidanceLevel: 3,
|
|
41
|
-
requiredArtifacts: ['ResponseCompression', 'GatherContext', 'devtoolsLogs', 'traces', 'URL'
|
|
41
|
+
requiredArtifacts: ['ResponseCompression', 'GatherContext', 'devtoolsLogs', 'traces', 'URL',
|
|
42
|
+
'SourceMaps'],
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -38,7 +38,7 @@ class CriticalRequestChains extends Audit {
|
|
|
38
38
|
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
|
|
39
39
|
supportedModes: ['navigation'],
|
|
40
40
|
guidanceLevel: 1,
|
|
41
|
-
requiredArtifacts: ['traces', 'devtoolsLogs', 'URL'],
|
|
41
|
+
requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'SourceMaps'],
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -168,10 +168,12 @@ class CriticalRequestChains extends Audit {
|
|
|
168
168
|
* @return {Promise<LH.Audit.Product>}
|
|
169
169
|
*/
|
|
170
170
|
static async audit(artifacts, context) {
|
|
171
|
+
const settings = context.settings;
|
|
171
172
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
172
173
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
173
|
-
const URL = artifacts
|
|
174
|
-
const chains =
|
|
174
|
+
const {URL, SourceMaps} = artifacts;
|
|
175
|
+
const chains =
|
|
176
|
+
await ComputedChains.request({settings, devtoolsLog, trace, URL, SourceMaps}, context);
|
|
175
177
|
let chainCount = 0;
|
|
176
178
|
/**
|
|
177
179
|
* @param {LH.Audit.Details.SimpleCriticalRequestNode} node
|
|
@@ -56,7 +56,7 @@ class DOMSize extends Audit {
|
|
|
56
56
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
57
57
|
guidanceLevel: 1,
|
|
58
58
|
requiredArtifacts: ['DOMStats', 'URL', 'GatherContext'],
|
|
59
|
-
__internalOptionalArtifacts: ['traces', 'devtoolsLogs'],
|
|
59
|
+
__internalOptionalArtifacts: ['traces', 'devtoolsLogs', 'SourceMaps'],
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -58,7 +58,7 @@ class UsesHTTP2Audit extends Audit {
|
|
|
58
58
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
59
59
|
guidanceLevel: 3,
|
|
60
60
|
supportedModes: ['timespan', 'navigation'],
|
|
61
|
-
requiredArtifacts: ['URL', 'devtoolsLogs', 'traces', 'GatherContext'],
|
|
61
|
+
requiredArtifacts: ['URL', 'devtoolsLogs', 'traces', 'GatherContext', 'SourceMaps'],
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -39,7 +39,7 @@ class CLSCulpritsInsight extends Audit {
|
|
|
39
39
|
failureTitle: insightStr_(InsightUIStrings.title),
|
|
40
40
|
description: insightStr_(InsightUIStrings.description),
|
|
41
41
|
guidanceLevel: 3,
|
|
42
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
42
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
43
43
|
replacesAudits: ['layout-shifts', 'non-composited-animations', 'unsized-images'],
|
|
44
44
|
};
|
|
45
45
|
}
|
|
@@ -24,7 +24,7 @@ class DocumentLatencyInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['redirects', 'server-response-time', 'uses-text-compression'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ class DOMSizeInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['dom-size'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export default
|
|
2
|
-
declare class
|
|
1
|
+
export default DuplicatedJavaScriptInsight;
|
|
2
|
+
declare class DuplicatedJavaScriptInsight extends Audit {
|
|
3
3
|
/**
|
|
4
4
|
* @param {LH.Artifacts} artifacts
|
|
5
5
|
* @param {LH.Audit.Context} context
|
|
@@ -8,4 +8,4 @@ declare class LongCriticalNetworkTreeInsight extends Audit {
|
|
|
8
8
|
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
9
9
|
}
|
|
10
10
|
import { Audit } from '../audit.js';
|
|
11
|
-
//# sourceMappingURL=
|
|
11
|
+
//# sourceMappingURL=duplicated-javascript-insight.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
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/DuplicatedJavaScript.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/DuplicatedJavaScript.js', UIStrings);
|
|
17
|
+
|
|
18
|
+
class DuplicatedJavaScriptInsight extends Audit {
|
|
19
|
+
/**
|
|
20
|
+
* @return {LH.Audit.Meta}
|
|
21
|
+
*/
|
|
22
|
+
static get meta() {
|
|
23
|
+
return {
|
|
24
|
+
id: 'duplicated-javascript-insight',
|
|
25
|
+
title: str_(UIStrings.title),
|
|
26
|
+
failureTitle: str_(UIStrings.title),
|
|
27
|
+
description: str_(UIStrings.description),
|
|
28
|
+
guidanceLevel: 3, // TODO: confirm/change.
|
|
29
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
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, 'DuplicatedJavaScript', (insight) => {
|
|
41
|
+
/** @type {LH.Audit.Details.Table['headings']} */
|
|
42
|
+
const headings = [
|
|
43
|
+
/* eslint-disable max-len */
|
|
44
|
+
/* eslint-enable max-len */
|
|
45
|
+
];
|
|
46
|
+
/** @type {LH.Audit.Details.Table['items']} */
|
|
47
|
+
const items = [
|
|
48
|
+
];
|
|
49
|
+
return Audit.makeTableDetails(headings, items);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default DuplicatedJavaScriptInsight;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */ // TODO: remove once implemented.
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @license
|
|
5
3
|
* Copyright 2025 Google LLC
|
|
@@ -10,7 +8,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/FontDispl
|
|
|
10
8
|
|
|
11
9
|
import {Audit} from '../audit.js';
|
|
12
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
|
-
import {adaptInsightToAuditProduct
|
|
11
|
+
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
14
12
|
|
|
15
13
|
// eslint-disable-next-line max-len
|
|
16
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js', UIStrings);
|
|
@@ -26,7 +24,7 @@ class FontDisplayInsight extends Audit {
|
|
|
26
24
|
failureTitle: str_(UIStrings.title),
|
|
27
25
|
description: str_(UIStrings.description),
|
|
28
26
|
guidanceLevel: 3,
|
|
29
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
30
28
|
replacesAudits: ['font-display'],
|
|
31
29
|
};
|
|
32
30
|
}
|
|
@@ -37,14 +35,17 @@ class FontDisplayInsight extends Audit {
|
|
|
37
35
|
* @return {Promise<LH.Audit.Product>}
|
|
38
36
|
*/
|
|
39
37
|
static async audit(artifacts, context) {
|
|
40
|
-
// TODO: implement.
|
|
41
38
|
return adaptInsightToAuditProduct(artifacts, context, 'FontDisplay', (insight) => {
|
|
42
39
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
43
40
|
const headings = [
|
|
41
|
+
{key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
|
|
42
|
+
{key: 'wastedMs', valueType: 'ms', label: str_(i18n.UIStrings.columnWastedMs)},
|
|
44
43
|
];
|
|
45
44
|
/** @type {LH.Audit.Details.Table['items']} */
|
|
46
|
-
const items =
|
|
47
|
-
|
|
45
|
+
const items = insight.fonts.map(font => ({
|
|
46
|
+
url: font.request.args.data.url,
|
|
47
|
+
wastedMs: font.wastedTime,
|
|
48
|
+
}));
|
|
48
49
|
return Audit.makeTableDetails(headings, items);
|
|
49
50
|
});
|
|
50
51
|
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
export default ForcedReflowInsight;
|
|
2
2
|
declare class ForcedReflowInsight extends Audit {
|
|
3
|
+
/**
|
|
4
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/ForcedReflow.js').ForcedReflowAggregatedData} topLevelFunctionCallData
|
|
5
|
+
* @returns {LH.Audit.Details.Table}
|
|
6
|
+
*/
|
|
7
|
+
static makeTopFunctionTable(topLevelFunctionCallData: import("@paulirish/trace_engine/models/trace/insights/ForcedReflow.js").ForcedReflowAggregatedData): LH.Audit.Details.Table;
|
|
8
|
+
/**
|
|
9
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/ForcedReflow.js').ForcedReflowInsightModel} insight
|
|
10
|
+
* @returns {LH.Audit.Details.Table}
|
|
11
|
+
*/
|
|
12
|
+
static makeBottomUpTable(insight: import("@paulirish/trace_engine/models/trace/insights/ForcedReflow.js").ForcedReflowInsightModel): LH.Audit.Details.Table;
|
|
3
13
|
/**
|
|
4
14
|
* @param {LH.Artifacts} artifacts
|
|
5
15
|
* @param {LH.Audit.Context} context
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */ // TODO: remove once implemented.
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @license
|
|
5
3
|
* Copyright 2025 Google LLC
|
|
@@ -10,7 +8,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/ForcedRef
|
|
|
10
8
|
|
|
11
9
|
import {Audit} from '../audit.js';
|
|
12
10
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
|
-
import {adaptInsightToAuditProduct
|
|
11
|
+
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
14
12
|
|
|
15
13
|
// eslint-disable-next-line max-len
|
|
16
14
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js', UIStrings);
|
|
@@ -26,25 +24,79 @@ class ForcedReflowInsight extends Audit {
|
|
|
26
24
|
failureTitle: str_(UIStrings.title),
|
|
27
25
|
description: str_(UIStrings.description),
|
|
28
26
|
guidanceLevel: 3,
|
|
29
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
30
28
|
};
|
|
31
29
|
}
|
|
32
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/ForcedReflow.js').ForcedReflowAggregatedData} topLevelFunctionCallData
|
|
33
|
+
* @returns {LH.Audit.Details.Table}
|
|
34
|
+
*/
|
|
35
|
+
static makeTopFunctionTable(topLevelFunctionCallData) {
|
|
36
|
+
const {topLevelFunctionCall} = topLevelFunctionCallData;
|
|
37
|
+
/** @type {LH.Audit.Details.Table['headings']} */
|
|
38
|
+
const headings = [
|
|
39
|
+
// eslint-disable-next-line max-len
|
|
40
|
+
{key: 'source', valueType: 'source-location', label: str_(UIStrings.topTimeConsumingFunctionCall)},
|
|
41
|
+
{key: 'reflowTime', valueType: 'ms', granularity: 1, label: str_(UIStrings.totalReflowTime)},
|
|
42
|
+
];
|
|
43
|
+
/** @type {LH.Audit.Details.Table['items']} */
|
|
44
|
+
const items = [
|
|
45
|
+
{
|
|
46
|
+
source: Audit.makeSourceLocation(
|
|
47
|
+
topLevelFunctionCall.url,
|
|
48
|
+
topLevelFunctionCall.lineNumber,
|
|
49
|
+
topLevelFunctionCall.columnNumber
|
|
50
|
+
),
|
|
51
|
+
reflowTime: topLevelFunctionCallData.totalReflowTime / 1000,
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
return Audit.makeTableDetails(headings, items);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {import('@paulirish/trace_engine/models/trace/insights/ForcedReflow.js').ForcedReflowInsightModel} insight
|
|
59
|
+
* @returns {LH.Audit.Details.Table}
|
|
60
|
+
*/
|
|
61
|
+
static makeBottomUpTable(insight) {
|
|
62
|
+
/** @type {LH.Audit.Details.Table['headings']} */
|
|
63
|
+
const headings = [
|
|
64
|
+
{key: 'source', valueType: 'source-location', label: str_(i18n.UIStrings.columnSource)},
|
|
65
|
+
{key: 'reflowTime', valueType: 'ms', granularity: 1, label: str_(UIStrings.totalReflowTime)},
|
|
66
|
+
];
|
|
67
|
+
/** @type {LH.Audit.Details.Table['items']} */
|
|
68
|
+
const items = insight.aggregatedBottomUpData.map((data) => {
|
|
69
|
+
const {bottomUpData, totalTime} = data;
|
|
70
|
+
|
|
71
|
+
const source = bottomUpData ? Audit.makeSourceLocation(
|
|
72
|
+
bottomUpData.url,
|
|
73
|
+
bottomUpData.lineNumber,
|
|
74
|
+
bottomUpData.columnNumber
|
|
75
|
+
) : {
|
|
76
|
+
type: /** @type {const} */ ('text'),
|
|
77
|
+
value: str_(UIStrings.unattributed),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
source,
|
|
82
|
+
reflowTime: totalTime / 1000,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
return Audit.makeTableDetails(headings, items);
|
|
86
|
+
}
|
|
87
|
+
|
|
33
88
|
/**
|
|
34
89
|
* @param {LH.Artifacts} artifacts
|
|
35
90
|
* @param {LH.Audit.Context} context
|
|
36
91
|
* @return {Promise<LH.Audit.Product>}
|
|
37
92
|
*/
|
|
38
93
|
static async audit(artifacts, context) {
|
|
39
|
-
// TODO: implement.
|
|
40
94
|
return adaptInsightToAuditProduct(artifacts, context, 'ForcedReflow', (insight) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
];
|
|
47
|
-
return Audit.makeTableDetails(headings, items);
|
|
95
|
+
const list = [this.makeBottomUpTable(insight)];
|
|
96
|
+
if (insight.topLevelFunctionCallData) {
|
|
97
|
+
list.unshift(this.makeTopFunctionTable(insight.topLevelFunctionCallData));
|
|
98
|
+
}
|
|
99
|
+
return Audit.makeListDetails(list);
|
|
48
100
|
});
|
|
49
101
|
}
|
|
50
102
|
}
|
|
@@ -4,15 +4,20 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import * as ImageDeliveryInsightModule from '@paulirish/trace_engine/models/trace/insights/ImageDelivery.js';
|
|
7
8
|
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/ImageDelivery.js';
|
|
8
9
|
|
|
9
10
|
import {Audit} from '../audit.js';
|
|
10
11
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
11
12
|
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
13
|
+
import {TraceEngineResult} from '../../computed/trace-engine-result.js';
|
|
12
14
|
|
|
13
15
|
// eslint-disable-next-line max-len
|
|
14
16
|
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js', UIStrings);
|
|
15
17
|
|
|
18
|
+
const getOptimizationMessage =
|
|
19
|
+
TraceEngineResult.localizeFunction(str_, ImageDeliveryInsightModule.getOptimizationMessage);
|
|
20
|
+
|
|
16
21
|
class ImageDeliveryInsight extends Audit {
|
|
17
22
|
/**
|
|
18
23
|
* @return {LH.Audit.Meta}
|
|
@@ -24,7 +29,7 @@ class ImageDeliveryInsight extends Audit {
|
|
|
24
29
|
failureTitle: str_(UIStrings.title),
|
|
25
30
|
description: str_(UIStrings.description),
|
|
26
31
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
32
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
33
|
replacesAudits: [
|
|
29
34
|
'modern-image-formats',
|
|
30
35
|
'uses-optimized-images',
|
|
@@ -46,10 +51,6 @@ class ImageDeliveryInsight extends Audit {
|
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
const relatedEventsMap = insight.relatedEvents && !Array.isArray(insight.relatedEvents) ?
|
|
50
|
-
insight.relatedEvents :
|
|
51
|
-
null;
|
|
52
|
-
|
|
53
54
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
54
55
|
const headings = [
|
|
55
56
|
/* eslint-disable max-len */
|
|
@@ -66,11 +67,9 @@ class ImageDeliveryInsight extends Audit {
|
|
|
66
67
|
wastedBytes: image.byteSavings,
|
|
67
68
|
subItems: {
|
|
68
69
|
type: /** @type {const} */ ('subitems'),
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
reason,
|
|
73
|
-
wastedBytes: image.optimizations[i].byteSavings,
|
|
70
|
+
items: image.optimizations.map(optimization => ({
|
|
71
|
+
reason: getOptimizationMessage(optimization),
|
|
72
|
+
wastedBytes: optimization.byteSavings,
|
|
74
73
|
})),
|
|
75
74
|
},
|
|
76
75
|
}));
|
|
@@ -16,9 +16,11 @@ import {Audit} from '../audit.js';
|
|
|
16
16
|
* @return {Promise<import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined>}
|
|
17
17
|
*/
|
|
18
18
|
async function getInsightSet(artifacts, context) {
|
|
19
|
+
const settings = context.settings;
|
|
19
20
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
20
21
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
21
|
-
const
|
|
22
|
+
const SourceMaps = artifacts.SourceMaps;
|
|
23
|
+
const traceEngineResult = await TraceEngineResult.request({trace, settings, SourceMaps}, context);
|
|
22
24
|
|
|
23
25
|
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
|
|
24
26
|
const key = navigationId ?? NO_NAVIGATION;
|
|
@@ -71,11 +73,14 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
|
|
|
71
73
|
metricSavings = {...metricSavings, LCP: /** @type {any} */ (0)};
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
let score =
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
let score = 1;
|
|
77
|
+
if (insight.state === 'fail') {
|
|
78
|
+
score = 0;
|
|
79
|
+
} else if (insightName === 'LCPPhases') {
|
|
80
|
+
// TODO: change these insights to denote passing/failing/informative. Until then... hack it.
|
|
77
81
|
score = metricSavings?.LCP ?? 0 >= 1000 ? 0 : 1;
|
|
78
82
|
} else if (insightName === 'InteractionToNextPaint') {
|
|
83
|
+
// TODO: change these insights to denote passing/failing/informative. Until then... hack it.
|
|
79
84
|
score = metricSavings?.INP ?? 0 >= 500 ? 0 : 1;
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -24,7 +24,7 @@ class InteractionToNextPaintInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['work-during-interaction'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ class LCPDiscoveryInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['prioritize-lcp-image', 'lcp-lazy-loaded'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ class LCPPhasesInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['largest-contentful-paint-element'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default NetworkDependencyTreeInsight;
|
|
2
|
+
declare class NetworkDependencyTreeInsight 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=network-dependency-tree-insight.d.ts.map
|
|
@@ -6,27 +6,27 @@
|
|
|
6
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/
|
|
9
|
+
import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js';
|
|
10
10
|
|
|
11
11
|
import {Audit} from '../audit.js';
|
|
12
12
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
13
13
|
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line max-len
|
|
16
|
-
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/
|
|
16
|
+
const str_ = i18n.createIcuMessageFn('node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js', UIStrings);
|
|
17
17
|
|
|
18
|
-
class
|
|
18
|
+
class NetworkDependencyTreeInsight extends Audit {
|
|
19
19
|
/**
|
|
20
20
|
* @return {LH.Audit.Meta}
|
|
21
21
|
*/
|
|
22
22
|
static get meta() {
|
|
23
23
|
return {
|
|
24
|
-
id: '
|
|
24
|
+
id: 'network-dependency-tree-insight',
|
|
25
25
|
title: str_(UIStrings.title),
|
|
26
26
|
failureTitle: str_(UIStrings.title),
|
|
27
27
|
description: str_(UIStrings.description),
|
|
28
28
|
guidanceLevel: 3,
|
|
29
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
29
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
30
30
|
replacesAudits: ['critical-request-chains'],
|
|
31
31
|
};
|
|
32
32
|
}
|
|
@@ -38,7 +38,7 @@ class LongCriticalNetworkTreeInsight extends Audit {
|
|
|
38
38
|
*/
|
|
39
39
|
static async audit(artifacts, context) {
|
|
40
40
|
// TODO: implement.
|
|
41
|
-
return adaptInsightToAuditProduct(artifacts, context, '
|
|
41
|
+
return adaptInsightToAuditProduct(artifacts, context, 'NetworkDependencyTree', (insight) => {
|
|
42
42
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
43
43
|
const headings = [
|
|
44
44
|
];
|
|
@@ -50,4 +50,4 @@ class LongCriticalNetworkTreeInsight extends Audit {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export default
|
|
53
|
+
export default NetworkDependencyTreeInsight;
|
|
@@ -24,7 +24,7 @@ class RenderBlockingInsight extends Audit {
|
|
|
24
24
|
failureTitle: str_(UIStrings.title),
|
|
25
25
|
description: str_(UIStrings.description),
|
|
26
26
|
guidanceLevel: 3,
|
|
27
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
27
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
28
28
|
replacesAudits: ['render-blocking-resources'],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -26,7 +26,7 @@ class SlowCSSSelectorInsight extends Audit {
|
|
|
26
26
|
failureTitle: str_(UIStrings.title),
|
|
27
27
|
description: str_(UIStrings.description),
|
|
28
28
|
guidanceLevel: 3,
|
|
29
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
29
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -31,7 +31,7 @@ class ThirdPartiesInsight extends Audit {
|
|
|
31
31
|
failureTitle: str_(UIStrings.title),
|
|
32
32
|
description: str_(UIStrings.description),
|
|
33
33
|
guidanceLevel: 3,
|
|
34
|
-
requiredArtifacts: ['traces', 'TraceElements'],
|
|
34
|
+
requiredArtifacts: ['traces', 'TraceElements', 'SourceMaps'],
|
|
35
35
|
replacesAudits: ['third-party-summary'],
|
|
36
36
|
};
|
|
37
37
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default UseCacheInsight;
|
|
2
|
+
declare class UseCacheInsight 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=use-cache-insight.d.ts.map
|