lighthouse 11.7.0-dev.20240320 → 11.7.0-dev.20240322
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/CONTRIBUTING.md +2 -2
- package/core/audits/preload-fonts.d.ts +1 -5
- package/core/audits/preload-fonts.js +1 -10
- package/core/audits/uses-rel-preload.d.ts +1 -5
- package/core/audits/uses-rel-preload.js +1 -11
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/module-duplication.d.ts +1 -1
- package/core/config/default-config.js +0 -5
- package/core/config/experimental-config.js +11 -0
- package/core/config/metrics-to-audits.js +0 -2
- package/package.json +1 -1
- package/types/artifacts.d.ts +2 -4
- package/core/audits/script-elements-test-audit.d.ts +0 -14
- package/core/audits/script-elements-test-audit.js +0 -29
- package/core/gather/gatherers/script-elements.d.ts +0 -21
- package/core/gather/gatherers/script-elements.js +0 -100
package/CONTRIBUTING.md
CHANGED
|
@@ -79,8 +79,8 @@ A PR adding or changing a gatherer almost always needs to include the following:
|
|
|
79
79
|
1. **Golden artifacts**: `sample_v2.json` is generated from a set of artifacts that come from running LH against `dbw_tester.html`. Those artifacts likely need to be updated after gatherer changes with `yarn update:sample-artifacts`, but limit to just the artifact being altered if possible. For example:
|
|
80
80
|
|
|
81
81
|
```sh
|
|
82
|
-
# update just the
|
|
83
|
-
yarn update:sample-artifacts
|
|
82
|
+
# update just the Scripts artifact
|
|
83
|
+
yarn update:sample-artifacts Scripts
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
This command works for updating `yarn update:sample-artifacts DevtoolsLog` or `Trace` as well, but the resulting `sample_v2.json` churn may be extensive and you might be better off editing manually.
|
|
@@ -14,11 +14,7 @@ declare class PreloadFontsAudit extends Audit {
|
|
|
14
14
|
* @param {LH.Audit.Context} context
|
|
15
15
|
* @return {Promise<LH.Audit.Product>}
|
|
16
16
|
*/
|
|
17
|
-
static
|
|
18
|
-
/**
|
|
19
|
-
* @return {Promise<LH.Audit.Product>}
|
|
20
|
-
*/
|
|
21
|
-
static audit(): Promise<LH.Audit.Product>;
|
|
17
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
22
18
|
}
|
|
23
19
|
export namespace UIStrings {
|
|
24
20
|
const title: string;
|
|
@@ -62,7 +62,7 @@ class PreloadFontsAudit extends Audit {
|
|
|
62
62
|
* @param {LH.Audit.Context} context
|
|
63
63
|
* @return {Promise<LH.Audit.Product>}
|
|
64
64
|
*/
|
|
65
|
-
static async
|
|
65
|
+
static async audit(artifacts, context) {
|
|
66
66
|
const devtoolsLog = artifacts.devtoolsLogs[this.DEFAULT_PASS];
|
|
67
67
|
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
68
68
|
|
|
@@ -91,15 +91,6 @@ class PreloadFontsAudit extends Audit {
|
|
|
91
91
|
notApplicable: optionalFontURLs.size === 0,
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @return {Promise<LH.Audit.Product>}
|
|
97
|
-
*/
|
|
98
|
-
static async audit() {
|
|
99
|
-
// Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
|
|
100
|
-
// is resolved.
|
|
101
|
-
return {score: 1, notApplicable: true};
|
|
102
|
-
}
|
|
103
94
|
}
|
|
104
95
|
|
|
105
96
|
export default PreloadFontsAudit;
|
|
@@ -45,11 +45,7 @@ declare class UsesRelPreloadAudit extends Audit {
|
|
|
45
45
|
* @param {LH.Audit.Context} context
|
|
46
46
|
* @return {Promise<LH.Audit.Product>}
|
|
47
47
|
*/
|
|
48
|
-
static
|
|
49
|
-
/**
|
|
50
|
-
* @return {Promise<LH.Audit.Product>}
|
|
51
|
-
*/
|
|
52
|
-
static audit(): Promise<LH.Audit.Product>;
|
|
48
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
53
49
|
}
|
|
54
50
|
export namespace UIStrings {
|
|
55
51
|
const title: string;
|
|
@@ -209,7 +209,7 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
209
209
|
* @param {LH.Audit.Context} context
|
|
210
210
|
* @return {Promise<LH.Audit.Product>}
|
|
211
211
|
*/
|
|
212
|
-
static async
|
|
212
|
+
static async audit(artifacts, context) {
|
|
213
213
|
const trace = artifacts.traces[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
214
214
|
const devtoolsLog = artifacts.devtoolsLogs[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
215
215
|
const URL = artifacts.URL;
|
|
@@ -253,16 +253,6 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
253
253
|
warnings,
|
|
254
254
|
};
|
|
255
255
|
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* @return {Promise<LH.Audit.Product>}
|
|
259
|
-
*/
|
|
260
|
-
static async audit() {
|
|
261
|
-
// Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
|
|
262
|
-
// is resolved.
|
|
263
|
-
return {score: 1, notApplicable: true,
|
|
264
|
-
details: Audit.makeOpportunityDetails([], [], {overallSavingsMs: 0})};
|
|
265
|
-
}
|
|
266
256
|
}
|
|
267
257
|
|
|
268
258
|
export default UsesRelPreloadAudit;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JSBundlesComputed as JSBundles };
|
|
2
2
|
declare const JSBundlesComputed: typeof JSBundles & {
|
|
3
|
-
request: (dependencies: Pick<import("../index.js").Artifacts, "
|
|
3
|
+
request: (dependencies: Pick<import("../index.js").Artifacts, "SourceMaps" | "Scripts">, context: import("../../types/utility-types.js").default.ImmutableObject<{
|
|
4
4
|
computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
|
|
5
5
|
}>) => Promise<import("../index.js").Artifacts.Bundle[]>;
|
|
6
6
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ModuleDuplicationComputed as ModuleDuplication };
|
|
2
2
|
declare const ModuleDuplicationComputed: typeof ModuleDuplication & {
|
|
3
|
-
request: (dependencies: Pick<import("../index.js").Artifacts, "
|
|
3
|
+
request: (dependencies: Pick<import("../index.js").Artifacts, "SourceMaps" | "Scripts">, context: import("../../types/utility-types.js").default.ImmutableObject<{
|
|
4
4
|
computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
|
|
5
5
|
}>) => Promise<Map<string, {
|
|
6
6
|
scriptId: string;
|
|
@@ -155,7 +155,6 @@ const defaultConfig = {
|
|
|
155
155
|
{id: 'ResponseCompression', gatherer: 'dobetterweb/response-compression'},
|
|
156
156
|
{id: 'RobotsTxt', gatherer: 'seo/robots-txt'},
|
|
157
157
|
{id: 'ServiceWorker', gatherer: 'service-worker'},
|
|
158
|
-
{id: 'ScriptElements', gatherer: 'script-elements'},
|
|
159
158
|
{id: 'Scripts', gatherer: 'scripts'},
|
|
160
159
|
{id: 'SourceMaps', gatherer: 'source-maps'},
|
|
161
160
|
{id: 'Stacks', gatherer: 'stacks'},
|
|
@@ -201,12 +200,10 @@ const defaultConfig = {
|
|
|
201
200
|
'content-width',
|
|
202
201
|
'image-aspect-ratio',
|
|
203
202
|
'image-size-responsive',
|
|
204
|
-
'preload-fonts',
|
|
205
203
|
'deprecations',
|
|
206
204
|
'third-party-cookies',
|
|
207
205
|
'mainthread-work-breakdown',
|
|
208
206
|
'bootup-time',
|
|
209
|
-
'uses-rel-preload',
|
|
210
207
|
'uses-rel-preconnect',
|
|
211
208
|
'font-display',
|
|
212
209
|
'diagnostics',
|
|
@@ -460,7 +457,6 @@ const defaultConfig = {
|
|
|
460
457
|
{id: 'uses-rel-preconnect', weight: 0},
|
|
461
458
|
{id: 'server-response-time', weight: 0},
|
|
462
459
|
{id: 'redirects', weight: 0},
|
|
463
|
-
{id: 'uses-rel-preload', weight: 0},
|
|
464
460
|
{id: 'uses-http2', weight: 0},
|
|
465
461
|
{id: 'efficient-animated-content', weight: 0},
|
|
466
462
|
{id: 'duplicated-javascript', weight: 0},
|
|
@@ -605,7 +601,6 @@ const defaultConfig = {
|
|
|
605
601
|
{id: 'paste-preventing-inputs', weight: 3, group: 'best-practices-ux'},
|
|
606
602
|
{id: 'image-aspect-ratio', weight: 1, group: 'best-practices-ux'},
|
|
607
603
|
{id: 'image-size-responsive', weight: 1, group: 'best-practices-ux'},
|
|
608
|
-
{id: 'preload-fonts', weight: 1, group: 'best-practices-ux'},
|
|
609
604
|
// Browser Compatibility
|
|
610
605
|
{id: 'doctype', weight: 1, group: 'best-practices-browser-compat'},
|
|
611
606
|
{id: 'charset', weight: 1, group: 'best-practices-browser-compat'},
|
|
@@ -14,13 +14,24 @@ const config = {
|
|
|
14
14
|
extends: 'lighthouse:default',
|
|
15
15
|
audits: [
|
|
16
16
|
'autocomplete',
|
|
17
|
+
// Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
|
|
18
|
+
'preload-fonts',
|
|
19
|
+
'uses-rel-preload',
|
|
17
20
|
],
|
|
18
21
|
categories: {
|
|
22
|
+
// @ts-ignore: `title` is required in CategoryJson. setting to the same value as the default
|
|
23
|
+
// config is awkward - easier to omit the property here. Will defer to default config.
|
|
24
|
+
'performance': {
|
|
25
|
+
auditRefs: [
|
|
26
|
+
{id: 'uses-rel-preload', weight: 0},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
19
29
|
// @ts-ignore: `title` is required in CategoryJson. setting to the same value as the default
|
|
20
30
|
// config is awkward - easier to omit the property here. Will defer to default config.
|
|
21
31
|
'best-practices': {
|
|
22
32
|
auditRefs: [
|
|
23
33
|
{id: 'autocomplete', weight: 0, group: 'best-practices-ux'},
|
|
34
|
+
{id: 'preload-fonts', weight: 0, group: 'best-practices-ux'},
|
|
24
35
|
],
|
|
25
36
|
},
|
|
26
37
|
},
|
|
@@ -12,7 +12,6 @@ const fcpRelevantAudits = [
|
|
|
12
12
|
'critical-request-chains',
|
|
13
13
|
'uses-text-compression',
|
|
14
14
|
'uses-rel-preconnect',
|
|
15
|
-
'uses-rel-preload',
|
|
16
15
|
'font-display',
|
|
17
16
|
'unminified-javascript',
|
|
18
17
|
'unminified-css',
|
|
@@ -46,7 +45,6 @@ const clsRelevantAudits = [
|
|
|
46
45
|
'layout-shifts',
|
|
47
46
|
'non-composited-animations',
|
|
48
47
|
'unsized-images',
|
|
49
|
-
// 'preload-fonts', // actually in BP, rather than perf
|
|
50
48
|
];
|
|
51
49
|
|
|
52
50
|
const inpRelevantAudits = [
|
package/package.json
CHANGED
package/types/artifacts.d.ts
CHANGED
|
@@ -89,8 +89,8 @@ interface PublicGathererArtifacts {
|
|
|
89
89
|
LinkElements: Artifacts.LinkElement[];
|
|
90
90
|
/** The values of the <meta> elements in the head. */
|
|
91
91
|
MetaElements: Array<{name?: string, content?: string, property?: string, httpEquiv?: string, charset?: string, node: Artifacts.NodeDetails}>;
|
|
92
|
-
/** Information on all
|
|
93
|
-
|
|
92
|
+
/** Information on all scripts in the page. */
|
|
93
|
+
Scripts: Artifacts.Script[];
|
|
94
94
|
/** The dimensions and devicePixelRatio of the loaded viewport. */
|
|
95
95
|
ViewportDimensions: Artifacts.ViewportDimensions;
|
|
96
96
|
}
|
|
@@ -146,8 +146,6 @@ export interface GathererArtifacts extends PublicGathererArtifacts {
|
|
|
146
146
|
RobotsTxt: {status: number|null, content: string|null, errorMessage?: string};
|
|
147
147
|
/** The result of calling the shared trace engine root cause analysis. */
|
|
148
148
|
RootCauses: Artifacts.TraceEngineRootCauses;
|
|
149
|
-
/** Information on all scripts in the page. */
|
|
150
|
-
Scripts: Artifacts.Script[];
|
|
151
149
|
/** Version information for all ServiceWorkers active after the first page load. */
|
|
152
150
|
ServiceWorker: {versions: Crdp.ServiceWorker.ServiceWorkerVersion[], registrations: Crdp.ServiceWorker.ServiceWorkerRegistration[]};
|
|
153
151
|
/** Source maps of scripts executed in the page. */
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
declare namespace _default {
|
|
2
|
-
namespace meta {
|
|
3
|
-
const id: string;
|
|
4
|
-
const title: string;
|
|
5
|
-
const failureTitle: string;
|
|
6
|
-
const description: string;
|
|
7
|
-
const requiredArtifacts: string[];
|
|
8
|
-
}
|
|
9
|
-
function audit(): {
|
|
10
|
-
score: number;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export default _default;
|
|
14
|
-
//# sourceMappingURL=script-elements-test-audit.d.ts.map
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2022 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @fileoverview This is a fake audit used exclusively in smoke tests to force inclusion of ScriptElements artifact.
|
|
9
|
-
* It is included here for complex reasons in the way the bundled smoketests work.
|
|
10
|
-
*
|
|
11
|
-
* The smokehouse configs are evaluated first in the node CLI side (which requires an absolute path using LH_ROOT).
|
|
12
|
-
* The smokehouse configs are then *re-evaluated* in the bundled context for execution by Lighthouse (which *cannot* use an absolute path using LH_ROOT).
|
|
13
|
-
*
|
|
14
|
-
* This mismatch in environment demands that the audit path in the config must be context-aware,
|
|
15
|
-
* yet the require-graph for the config is included before even the CLI knows that it will be using
|
|
16
|
-
* a bundled runner. Rather than force a massive smoketest architecture change, we include a harmless,
|
|
17
|
-
* test-only audit in our core list instead.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
meta: {
|
|
22
|
-
id: 'script-elements-test-audit',
|
|
23
|
-
title: 'ScriptElements',
|
|
24
|
-
failureTitle: 'ScriptElements',
|
|
25
|
-
description: 'Audit to force the inclusion of ScriptElements artifact',
|
|
26
|
-
requiredArtifacts: ['ScriptElements'],
|
|
27
|
-
},
|
|
28
|
-
audit: () => ({score: 1}),
|
|
29
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export default ScriptElements;
|
|
2
|
-
/**
|
|
3
|
-
* @fileoverview Gets JavaScript file contents.
|
|
4
|
-
*/
|
|
5
|
-
declare class ScriptElements extends BaseGatherer {
|
|
6
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
7
|
-
meta: LH.Gatherer.GathererMeta<'DevtoolsLog'>;
|
|
8
|
-
/**
|
|
9
|
-
* @param {LH.Gatherer.Context} context
|
|
10
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
11
|
-
* @return {Promise<LH.Artifacts['ScriptElements']>}
|
|
12
|
-
*/
|
|
13
|
-
_getArtifact(context: LH.Gatherer.Context, networkRecords: LH.Artifacts.NetworkRequest[]): Promise<LH.Artifacts['ScriptElements']>;
|
|
14
|
-
/**
|
|
15
|
-
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
|
|
16
|
-
*/
|
|
17
|
-
getArtifact(context: LH.Gatherer.Context<'DevtoolsLog'>): Promise<import("../../index.js").Artifacts.ScriptElement[]>;
|
|
18
|
-
}
|
|
19
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
20
|
-
import { NetworkRequest } from '../../lib/network-request.js';
|
|
21
|
-
//# sourceMappingURL=script-elements.d.ts.map
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2017 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import BaseGatherer from '../base-gatherer.js';
|
|
8
|
-
import {NetworkRecords} from '../../computed/network-records.js';
|
|
9
|
-
import {NetworkRequest} from '../../lib/network-request.js';
|
|
10
|
-
import {pageFunctions} from '../../lib/page-functions.js';
|
|
11
|
-
import DevtoolsLog from './devtools-log.js';
|
|
12
|
-
|
|
13
|
-
/* global getNodeDetails */
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @return {LH.Artifacts['ScriptElements']}
|
|
17
|
-
*/
|
|
18
|
-
/* c8 ignore start */
|
|
19
|
-
function collectAllScriptElements() {
|
|
20
|
-
/** @type {HTMLScriptElement[]} */
|
|
21
|
-
// @ts-expect-error - getElementsInDocument put into scope via stringification
|
|
22
|
-
const scripts = getElementsInDocument('script'); // eslint-disable-line no-undef
|
|
23
|
-
|
|
24
|
-
return scripts.map(script => {
|
|
25
|
-
return {
|
|
26
|
-
type: script.type || null,
|
|
27
|
-
src: script.src || null,
|
|
28
|
-
id: script.id || null,
|
|
29
|
-
async: script.async,
|
|
30
|
-
defer: script.defer,
|
|
31
|
-
source: script.closest('head') ? 'head' : 'body',
|
|
32
|
-
// @ts-expect-error - getNodeDetails put into scope via stringification
|
|
33
|
-
node: getNodeDetails(script),
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
/* c8 ignore stop */
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @fileoverview Gets JavaScript file contents.
|
|
41
|
-
*/
|
|
42
|
-
class ScriptElements extends BaseGatherer {
|
|
43
|
-
/** @type {LH.Gatherer.GathererMeta<'DevtoolsLog'>} */
|
|
44
|
-
meta = {
|
|
45
|
-
supportedModes: ['timespan', 'navigation'],
|
|
46
|
-
dependencies: {DevtoolsLog: DevtoolsLog.symbol},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @param {LH.Gatherer.Context} context
|
|
51
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
52
|
-
* @return {Promise<LH.Artifacts['ScriptElements']>}
|
|
53
|
-
*/
|
|
54
|
-
async _getArtifact(context, networkRecords) {
|
|
55
|
-
const executionContext = context.driver.executionContext;
|
|
56
|
-
|
|
57
|
-
const scripts = await executionContext.evaluate(collectAllScriptElements, {
|
|
58
|
-
args: [],
|
|
59
|
-
useIsolation: true,
|
|
60
|
-
deps: [
|
|
61
|
-
pageFunctions.getNodeDetails,
|
|
62
|
-
pageFunctions.getElementsInDocument,
|
|
63
|
-
],
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const scriptRecords = networkRecords
|
|
67
|
-
.filter(record => record.resourceType === NetworkRequest.TYPES.Script)
|
|
68
|
-
.filter(record => record.sessionTargetType === 'page');
|
|
69
|
-
|
|
70
|
-
for (let i = 0; i < scriptRecords.length; i++) {
|
|
71
|
-
const record = scriptRecords[i];
|
|
72
|
-
|
|
73
|
-
const matchedScriptElement = scripts.find(script => script.src === record.url);
|
|
74
|
-
if (!matchedScriptElement) {
|
|
75
|
-
scripts.push({
|
|
76
|
-
type: null,
|
|
77
|
-
src: record.url,
|
|
78
|
-
id: null,
|
|
79
|
-
async: false,
|
|
80
|
-
defer: false,
|
|
81
|
-
source: 'network',
|
|
82
|
-
node: null,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return scripts;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @param {LH.Gatherer.Context<'DevtoolsLog'>} context
|
|
92
|
-
*/
|
|
93
|
-
async getArtifact(context) {
|
|
94
|
-
const devtoolsLog = context.dependencies.DevtoolsLog;
|
|
95
|
-
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
96
|
-
return this._getArtifact(context, networkRecords);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export default ScriptElements;
|