lighthouse 10.4.0 → 11.0.0
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 +1 -1
- package/cli/cli-flags.d.ts +1 -6
- package/cli/cli-flags.js +0 -5
- package/cli/run.js +3 -10
- package/cli/sentry-prompt.js +4 -2
- package/cli/test/smokehouse/core-tests.js +0 -2
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +24 -14
- package/cli/test/smokehouse/lighthouse-runners/bundle.d.ts +1 -2
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +12 -21
- package/cli/test/smokehouse/lighthouse-runners/cli.d.ts +1 -3
- package/cli/test/smokehouse/lighthouse-runners/cli.js +3 -7
- package/cli/test/smokehouse/lighthouse-runners/devtools.d.ts +1 -5
- package/cli/test/smokehouse/lighthouse-runners/devtools.js +1 -12
- package/cli/test/smokehouse/readme.md +0 -2
- package/cli/test/smokehouse/report-assert.d.ts +1 -3
- package/cli/test/smokehouse/report-assert.js +2 -19
- package/cli/test/smokehouse/smokehouse.js +3 -32
- package/core/audits/accessibility/aria-allowed-role.d.ts +10 -0
- package/core/audits/accessibility/aria-allowed-role.js +46 -0
- package/core/audits/accessibility/image-redundant-alt.d.ts +10 -0
- package/core/audits/accessibility/image-redundant-alt.js +45 -0
- package/core/audits/accessibility/label-content-name-mismatch.d.ts +10 -0
- package/core/audits/accessibility/label-content-name-mismatch.js +44 -0
- package/core/audits/accessibility/skip-link.d.ts +10 -0
- package/core/audits/accessibility/skip-link.js +43 -0
- package/core/audits/accessibility/table-duplicate-name.d.ts +10 -0
- package/core/audits/accessibility/table-duplicate-name.js +44 -0
- package/core/audits/accessibility/target-size.js +1 -1
- package/core/audits/byte-efficiency/duplicated-javascript.js +2 -2
- package/core/audits/byte-efficiency/render-blocking-resources.js +1 -0
- package/core/audits/dobetterweb/uses-http2.d.ts +18 -1
- package/core/audits/dobetterweb/uses-http2.js +62 -16
- package/core/audits/installable-manifest.d.ts +1 -5
- package/core/audits/installable-manifest.js +2 -7
- package/core/audits/largest-contentful-paint-element.d.ts +0 -6
- package/core/audits/largest-contentful-paint-element.js +13 -15
- package/core/audits/metrics/{experimental-interaction-to-next-paint.d.ts → interaction-to-next-paint.d.ts} +3 -3
- package/core/audits/metrics/{experimental-interaction-to-next-paint.js → interaction-to-next-paint.js} +3 -3
- package/core/audits/uses-rel-preconnect.js +23 -8
- package/core/audits/work-during-interaction.js +2 -2
- package/core/computed/processed-navigation.d.ts +1 -1
- package/core/config/config-helpers.d.ts +3 -3
- package/core/config/config-helpers.js +5 -12
- package/core/config/config.js +1 -7
- package/core/config/constants.d.ts +0 -2
- package/core/config/constants.js +2 -18
- package/core/config/default-config.js +59 -53
- package/core/config/filters.js +1 -1
- package/core/config/validation.d.ts +7 -12
- package/core/config/validation.js +16 -26
- package/core/gather/base-artifacts.d.ts +4 -4
- package/core/gather/base-artifacts.js +2 -6
- package/core/gather/base-gatherer.d.ts +12 -37
- package/core/gather/base-gatherer.js +7 -54
- package/core/gather/driver/dom.d.ts +4 -4
- package/core/gather/driver/dom.js +2 -2
- package/core/gather/driver/environment.d.ts +4 -4
- package/core/gather/driver/environment.js +2 -2
- package/core/gather/driver/execution-context.d.ts +12 -3
- package/core/gather/driver/execution-context.js +34 -3
- package/core/gather/driver/navigation.d.ts +2 -2
- package/core/gather/driver/navigation.js +2 -5
- package/core/gather/driver/network-monitor.d.ts +7 -6
- package/core/gather/driver/network-monitor.js +4 -4
- package/core/gather/driver/network.d.ts +2 -2
- package/core/gather/driver/network.js +1 -1
- package/core/gather/driver/prepare.d.ts +10 -10
- package/core/gather/driver/prepare.js +10 -10
- package/core/gather/driver/service-workers.d.ts +4 -4
- package/core/gather/driver/service-workers.js +2 -2
- package/core/gather/driver/storage.d.ts +6 -6
- package/core/gather/driver/storage.js +3 -3
- package/core/gather/driver/target-manager.d.ts +6 -5
- package/core/gather/driver/target-manager.js +3 -3
- package/core/gather/driver/wait-for-condition.d.ts +14 -14
- package/core/gather/driver/wait-for-condition.js +8 -8
- package/core/gather/driver.d.ts +9 -6
- package/core/gather/driver.js +14 -4
- package/core/gather/fetcher.d.ts +3 -3
- package/core/gather/fetcher.js +1 -1
- package/core/gather/gatherers/accessibility.d.ts +4 -4
- package/core/gather/gatherers/accessibility.js +8 -3
- package/core/gather/gatherers/anchor-elements.d.ts +4 -4
- package/core/gather/gatherers/anchor-elements.js +4 -4
- package/core/gather/gatherers/bf-cache-failures.d.ts +8 -14
- package/core/gather/gatherers/bf-cache-failures.js +5 -14
- package/core/gather/gatherers/cache-contents.d.ts +4 -4
- package/core/gather/gatherers/cache-contents.js +3 -3
- package/core/gather/gatherers/console-messages.d.ts +6 -6
- package/core/gather/gatherers/console-messages.js +4 -4
- package/core/gather/gatherers/css-usage.d.ts +14 -14
- package/core/gather/gatherers/css-usage.js +9 -9
- package/core/gather/gatherers/devtools-log-compat.d.ts +5 -5
- package/core/gather/gatherers/devtools-log-compat.js +4 -4
- package/core/gather/gatherers/devtools-log.d.ts +6 -6
- package/core/gather/gatherers/devtools-log.js +4 -4
- package/core/gather/gatherers/dobetterweb/doctype.d.ts +4 -4
- package/core/gather/gatherers/dobetterweb/doctype.js +3 -3
- package/core/gather/gatherers/dobetterweb/domstats.d.ts +4 -4
- package/core/gather/gatherers/dobetterweb/domstats.js +3 -3
- package/core/gather/gatherers/dobetterweb/optimized-images.d.ts +10 -22
- package/core/gather/gatherers/dobetterweb/optimized-images.js +10 -27
- package/core/gather/gatherers/dobetterweb/response-compression.d.ts +6 -12
- package/core/gather/gatherers/dobetterweb/response-compression.js +14 -21
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +8 -14
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +5 -14
- package/core/gather/gatherers/full-page-screenshot.d.ts +10 -10
- package/core/gather/gatherers/full-page-screenshot.js +7 -10
- package/core/gather/gatherers/global-listeners.d.ts +4 -4
- package/core/gather/gatherers/global-listeners.js +3 -3
- package/core/gather/gatherers/iframe-elements.d.ts +4 -4
- package/core/gather/gatherers/iframe-elements.js +3 -3
- package/core/gather/gatherers/image-elements.d.ts +10 -10
- package/core/gather/gatherers/image-elements.js +6 -6
- package/core/gather/gatherers/inputs.d.ts +4 -4
- package/core/gather/gatherers/inputs.js +3 -3
- package/core/gather/gatherers/inspector-issues.d.ts +8 -19
- package/core/gather/gatherers/inspector-issues.js +9 -26
- package/core/gather/gatherers/installability-errors.d.ts +6 -6
- package/core/gather/gatherers/installability-errors.js +4 -4
- package/core/gather/gatherers/js-usage.d.ts +6 -6
- package/core/gather/gatherers/js-usage.js +4 -4
- package/core/gather/gatherers/link-elements.d.ts +8 -20
- package/core/gather/gatherers/link-elements.js +7 -24
- package/core/gather/gatherers/main-document-content.d.ts +4 -16
- package/core/gather/gatherers/main-document-content.js +5 -23
- package/core/gather/gatherers/meta-elements.d.ts +4 -4
- package/core/gather/gatherers/meta-elements.js +3 -3
- package/core/gather/gatherers/network-user-agent.d.ts +5 -5
- package/core/gather/gatherers/network-user-agent.js +4 -4
- package/core/gather/gatherers/script-elements.d.ts +6 -11
- package/core/gather/gatherers/script-elements.js +4 -13
- package/core/gather/gatherers/scripts.d.ts +7 -6
- package/core/gather/gatherers/scripts.js +7 -9
- package/core/gather/gatherers/seo/embedded-content.d.ts +4 -4
- package/core/gather/gatherers/seo/embedded-content.js +3 -3
- package/core/gather/gatherers/seo/font-size.d.ts +6 -6
- package/core/gather/gatherers/seo/font-size.js +5 -5
- package/core/gather/gatherers/seo/robots-txt.d.ts +4 -4
- package/core/gather/gatherers/seo/robots-txt.js +3 -3
- package/core/gather/gatherers/seo/tap-targets.d.ts +8 -8
- package/core/gather/gatherers/seo/tap-targets.js +5 -5
- package/core/gather/gatherers/service-worker.d.ts +4 -10
- package/core/gather/gatherers/service-worker.js +3 -15
- package/core/gather/gatherers/source-maps.d.ts +11 -23
- package/core/gather/gatherers/source-maps.js +22 -53
- package/core/gather/gatherers/stacks.d.ts +7 -7
- package/core/gather/gatherers/stacks.js +6 -6
- package/core/gather/gatherers/trace-compat.d.ts +5 -5
- package/core/gather/gatherers/trace-compat.js +4 -4
- package/core/gather/gatherers/trace-elements.d.ts +13 -25
- package/core/gather/gatherers/trace-elements.js +19 -32
- package/core/gather/gatherers/trace.d.ts +8 -8
- package/core/gather/gatherers/trace.js +5 -5
- package/core/gather/gatherers/viewport-dimensions.d.ts +4 -4
- package/core/gather/gatherers/viewport-dimensions.js +3 -3
- package/core/gather/gatherers/web-app-manifest.d.ts +8 -8
- package/core/gather/gatherers/web-app-manifest.js +5 -5
- package/core/gather/navigation-runner.d.ts +9 -9
- package/core/gather/navigation-runner.js +14 -8
- package/core/gather/runner-helpers.d.ts +3 -3
- package/core/gather/runner-helpers.js +12 -4
- package/core/gather/session.d.ts +2 -2
- package/core/gather/session.js +1 -1
- package/core/gather/snapshot-runner.d.ts +2 -2
- package/core/gather/snapshot-runner.js +1 -1
- package/core/gather/timespan-runner.d.ts +2 -2
- package/core/gather/timespan-runner.js +1 -1
- package/core/index.cjs +0 -7
- package/core/index.d.ts +0 -15
- package/core/index.js +2 -40
- package/core/lib/asset-saver.js +14 -4
- package/core/lib/axe.js +1 -1
- package/core/lib/dependency-graph/simulator/network-analyzer.d.ts +28 -12
- package/core/lib/dependency-graph/simulator/network-analyzer.js +128 -100
- package/core/lib/emulation.d.ts +14 -14
- package/core/lib/emulation.js +7 -7
- package/core/lib/navigation-error.js +5 -0
- package/core/lib/network-recorder.d.ts +2 -1
- package/core/lib/network-recorder.js +1 -0
- package/core/lib/network-request.js +12 -3
- package/core/lib/page-functions.d.ts +10 -2
- package/core/lib/page-functions.js +85 -8
- package/core/lib/sentry.js +9 -2
- package/core/lib/stack-packs.js +4 -0
- package/core/runner.d.ts +8 -30
- package/core/runner.js +8 -39
- package/core/user-flow.d.ts +4 -4
- package/core/user-flow.js +2 -2
- package/dist/report/bundle.esm.js +2221 -5832
- package/dist/report/flow.js +2631 -235
- package/dist/report/standalone.js +2586 -234
- package/flow-report/src/i18n/i18n.d.ts +2 -2
- package/package.json +17 -24
- package/readme.md +3 -1
- package/report/assets/templates.html +3 -1
- package/report/renderer/category-renderer.d.ts +3 -2
- package/report/renderer/category-renderer.js +8 -4
- package/report/renderer/components.js +11 -5
- package/report/renderer/pwa-category-renderer.js +1 -1
- package/report/renderer/report-ui-features.js +9 -6
- package/report/renderer/report-utils.d.ts +1 -1
- package/report/renderer/report-utils.js +2 -2
- package/report/renderer/topbar-features.js +3 -0
- package/shared/localization/locales/ar-XB.json +185 -44
- package/shared/localization/locales/ar.json +185 -44
- package/shared/localization/locales/bg.json +185 -44
- package/shared/localization/locales/ca.json +190 -49
- package/shared/localization/locales/cs.json +185 -44
- package/shared/localization/locales/da.json +185 -44
- package/shared/localization/locales/de.json +185 -44
- package/shared/localization/locales/el.json +185 -44
- package/shared/localization/locales/en-GB.json +185 -44
- package/shared/localization/locales/en-US.json +99 -45
- package/shared/localization/locales/en-XA.json +185 -44
- package/shared/localization/locales/en-XL.json +99 -45
- package/shared/localization/locales/es-419.json +185 -44
- package/shared/localization/locales/es.json +185 -44
- package/shared/localization/locales/fi.json +185 -44
- package/shared/localization/locales/fil.json +185 -44
- package/shared/localization/locales/fr.json +185 -44
- package/shared/localization/locales/he.json +186 -45
- package/shared/localization/locales/hi.json +185 -44
- package/shared/localization/locales/hr.json +185 -44
- package/shared/localization/locales/hu.json +185 -44
- package/shared/localization/locales/id.json +185 -44
- package/shared/localization/locales/it.json +185 -44
- package/shared/localization/locales/ja.json +185 -44
- package/shared/localization/locales/ko.json +185 -44
- package/shared/localization/locales/lt.json +185 -44
- package/shared/localization/locales/lv.json +185 -44
- package/shared/localization/locales/nl.json +185 -44
- package/shared/localization/locales/no.json +185 -44
- package/shared/localization/locales/pl.json +185 -44
- package/shared/localization/locales/pt-PT.json +185 -44
- package/shared/localization/locales/pt.json +190 -49
- package/shared/localization/locales/ro.json +185 -44
- package/shared/localization/locales/ru.json +185 -44
- package/shared/localization/locales/sk.json +185 -44
- package/shared/localization/locales/sl.json +185 -44
- package/shared/localization/locales/sr-Latn.json +185 -44
- package/shared/localization/locales/sr.json +185 -44
- package/shared/localization/locales/sv.json +185 -44
- package/shared/localization/locales/ta.json +185 -44
- package/shared/localization/locales/te.json +185 -44
- package/shared/localization/locales/th.json +185 -44
- package/shared/localization/locales/tr.json +185 -44
- package/shared/localization/locales/uk.json +185 -44
- package/shared/localization/locales/vi.json +185 -44
- package/shared/localization/locales/zh-HK.json +185 -44
- package/shared/localization/locales/zh-TW.json +185 -44
- package/shared/localization/locales/zh.json +185 -44
- package/third-party/esbuild-plugins-polyfills/LICENSE +3 -0
- package/third-party/esbuild-plugins-polyfills/README.md +7 -0
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.d.ts +9 -0
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.js +129 -0
- package/tsconfig.json +2 -1
- package/types/artifacts.d.ts +16 -45
- package/types/config.d.ts +10 -52
- package/types/externs.d.ts +0 -2
- package/types/gatherer.d.ts +24 -47
- package/types/internal/rxjs.d.ts +26 -0
- package/types/internal/smokehouse.d.ts +1 -3
- package/types/lh.d.ts +0 -2
- package/types/lhr/settings.d.ts +1 -1
- package/core/audits/metrics/first-contentful-paint-3g.d.ts +0 -15
- package/core/audits/metrics/first-contentful-paint-3g.js +0 -69
- package/core/audits/resource-summary.d.ts +0 -16
- package/core/audits/resource-summary.js +0 -104
- package/core/audits/service-worker.d.ts +0 -46
- package/core/audits/service-worker.js +0 -182
- package/core/gather/gatherers/gatherer.d.ts +0 -46
- package/core/gather/gatherers/gatherer.js +0 -58
- package/core/legacy/config/config.d.ts +0 -107
- package/core/legacy/config/config.js +0 -566
- package/core/legacy/config/legacy-default-config.d.ts +0 -4
- package/core/legacy/config/legacy-default-config.js +0 -87
- package/core/legacy/gather/connections/connection.d.ts +0 -77
- package/core/legacy/gather/connections/connection.js +0 -196
- package/core/legacy/gather/connections/cri.d.ts +0 -27
- package/core/legacy/gather/connections/cri.js +0 -162
- package/core/legacy/gather/connections/raw.d.ts +0 -20
- package/core/legacy/gather/connections/raw.js +0 -57
- package/core/legacy/gather/driver.d.ts +0 -216
- package/core/legacy/gather/driver.js +0 -480
- package/core/legacy/gather/gather-runner.d.ts +0 -166
- package/core/legacy/gather/gather-runner.js +0 -590
- package/types/internal/lighthouse-logger.d.ts +0 -34
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Ensures <img> elements have alternative text that is not repeated text.
|
|
9
|
+
* See base class in axe-audit.js for audit() implementation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import AxeAudit from './axe-audit.js';
|
|
13
|
+
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
|
+
|
|
15
|
+
const UIStrings = {
|
|
16
|
+
/** Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute that is not redundant. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
|
+
title: 'Image elements do not have `[alt]` attributes that are redundant text.',
|
|
18
|
+
/** Title of an accesibility audit that evaluates if all image elements have the alt HTML attribute that is not redundant. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
|
+
failureTitle: 'Image elements have `[alt]` attributes that are redundant text.',
|
|
20
|
+
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
21
|
+
description: 'Informative elements should aim for short, descriptive alternative text. ' +
|
|
22
|
+
'Alternative text that is exactly the same as the text adjacent to the link or image is ' +
|
|
23
|
+
'potentially confusing for screen reader users, because the text will be read twice. ' +
|
|
24
|
+
'[Learn more about the `alt` attribute](https://dequeuniversity.com/rules/axe/4.7/image-redundant-alt).',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
28
|
+
|
|
29
|
+
class ImageRedundantAlt extends AxeAudit {
|
|
30
|
+
/**
|
|
31
|
+
* @return {LH.Audit.Meta}
|
|
32
|
+
*/
|
|
33
|
+
static get meta() {
|
|
34
|
+
return {
|
|
35
|
+
id: 'image-redundant-alt',
|
|
36
|
+
title: str_(UIStrings.title),
|
|
37
|
+
failureTitle: str_(UIStrings.failureTitle),
|
|
38
|
+
description: str_(UIStrings.description),
|
|
39
|
+
requiredArtifacts: ['Accessibility'],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default ImageRedundantAlt;
|
|
45
|
+
export {UIStrings};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default LabelContentNameMismatch;
|
|
2
|
+
declare class LabelContentNameMismatch extends AxeAudit {
|
|
3
|
+
}
|
|
4
|
+
export namespace UIStrings {
|
|
5
|
+
const title: string;
|
|
6
|
+
const failureTitle: string;
|
|
7
|
+
const description: string;
|
|
8
|
+
}
|
|
9
|
+
import AxeAudit from './axe-audit.js';
|
|
10
|
+
//# sourceMappingURL=label-content-name-mismatch.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Ensure that interactive elements labeled with their content have their visible label as part of their accessible name.
|
|
9
|
+
* See base class in axe-audit.js for audit() implementation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import AxeAudit from './axe-audit.js';
|
|
13
|
+
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
|
+
|
|
15
|
+
const UIStrings = {
|
|
16
|
+
/** Title of an accesibility audit that evaluates if elements labeled through their content have their visible text as part of their accessible name. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
|
+
title: 'Elements with visible text labels have matching accessible names.',
|
|
18
|
+
/** Title of an accesibility audit that evaluates if elements labeled through their content have their visible text as part of their accessible name. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
|
+
failureTitle: 'Elements with visible text labels do not have matching accessible names.',
|
|
20
|
+
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
21
|
+
description: 'Visible text labels that do not match the accessible name can result in a ' +
|
|
22
|
+
'confusing experience for screen reader users. ' +
|
|
23
|
+
'[Learn more about accessible names](https://dequeuniversity.com/rules/axe/4.7/label-content-name-mismatch).',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
27
|
+
|
|
28
|
+
class LabelContentNameMismatch extends AxeAudit {
|
|
29
|
+
/**
|
|
30
|
+
* @return {LH.Audit.Meta}
|
|
31
|
+
*/
|
|
32
|
+
static get meta() {
|
|
33
|
+
return {
|
|
34
|
+
id: 'label-content-name-mismatch',
|
|
35
|
+
title: str_(UIStrings.title),
|
|
36
|
+
failureTitle: str_(UIStrings.failureTitle),
|
|
37
|
+
description: str_(UIStrings.description),
|
|
38
|
+
requiredArtifacts: ['Accessibility'],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default LabelContentNameMismatch;
|
|
44
|
+
export {UIStrings};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default SkipLink;
|
|
2
|
+
declare class SkipLink extends AxeAudit {
|
|
3
|
+
}
|
|
4
|
+
export namespace UIStrings {
|
|
5
|
+
const title: string;
|
|
6
|
+
const failureTitle: string;
|
|
7
|
+
const description: string;
|
|
8
|
+
}
|
|
9
|
+
import AxeAudit from './axe-audit.js';
|
|
10
|
+
//# sourceMappingURL=skip-link.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Ensures that the skip-link target is focusable.
|
|
9
|
+
* See base class in axe-audit.js for audit() implementation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import AxeAudit from './axe-audit.js';
|
|
13
|
+
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
|
+
|
|
15
|
+
const UIStrings = {
|
|
16
|
+
/** Title of an accesibility audit that evaluates if the skip link is focusable. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
|
+
title: 'Skip links are focusable.',
|
|
18
|
+
/** Title of an accesibility audit that evaluates if the skip link is focusable. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
|
+
failureTitle: 'Skip links are not focusable.',
|
|
20
|
+
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
21
|
+
description: 'Including a skip link can help users skip to the main content to save time. ' +
|
|
22
|
+
'[Learn more about skip links](https://dequeuniversity.com/rules/axe/4.7/skip-link).',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
26
|
+
|
|
27
|
+
class SkipLink extends AxeAudit {
|
|
28
|
+
/**
|
|
29
|
+
* @return {LH.Audit.Meta}
|
|
30
|
+
*/
|
|
31
|
+
static get meta() {
|
|
32
|
+
return {
|
|
33
|
+
id: 'skip-link',
|
|
34
|
+
title: str_(UIStrings.title),
|
|
35
|
+
failureTitle: str_(UIStrings.failureTitle),
|
|
36
|
+
description: str_(UIStrings.description),
|
|
37
|
+
requiredArtifacts: ['Accessibility'],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default SkipLink;
|
|
43
|
+
export {UIStrings};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default TableDuplicateName;
|
|
2
|
+
declare class TableDuplicateName extends AxeAudit {
|
|
3
|
+
}
|
|
4
|
+
export namespace UIStrings {
|
|
5
|
+
const title: string;
|
|
6
|
+
const failureTitle: string;
|
|
7
|
+
const description: string;
|
|
8
|
+
}
|
|
9
|
+
import AxeAudit from './axe-audit.js';
|
|
10
|
+
//# sourceMappingURL=table-duplicate-name.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2023 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Ensure that table summary and caption have different content.
|
|
9
|
+
* See base class in axe-audit.js for audit() implementation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import AxeAudit from './axe-audit.js';
|
|
13
|
+
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
|
+
|
|
15
|
+
const UIStrings = {
|
|
16
|
+
/** Title of an accesibility audit that evaluates if tables have different content in the summary attribute and caption element. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
|
+
title: 'Tables have different content in the summary attribute and `<caption>`.',
|
|
18
|
+
/** Title of an accesibility audit that evaluates if tables have different content in the summary attribute and caption element. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
|
+
failureTitle: 'Tables have the same content in the summary attribute and `<caption>.`',
|
|
20
|
+
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
21
|
+
description: 'The summary attribute should describe the table structure, while `<caption>` ' +
|
|
22
|
+
'should have the onscreen title. Accurate table mark-up helps users of screen readers. ' +
|
|
23
|
+
'[Learn more about summary and caption](https://dequeuniversity.com/rules/axe/4.7/table-duplicate-name).',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
27
|
+
|
|
28
|
+
class TableDuplicateName extends AxeAudit {
|
|
29
|
+
/**
|
|
30
|
+
* @return {LH.Audit.Meta}
|
|
31
|
+
*/
|
|
32
|
+
static get meta() {
|
|
33
|
+
return {
|
|
34
|
+
id: 'table-duplicate-name',
|
|
35
|
+
title: str_(UIStrings.title),
|
|
36
|
+
failureTitle: str_(UIStrings.failureTitle),
|
|
37
|
+
description: str_(UIStrings.description),
|
|
38
|
+
requiredArtifacts: ['Accessibility'],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default TableDuplicateName;
|
|
44
|
+
export {UIStrings};
|
|
@@ -19,7 +19,7 @@ const UIStrings = {
|
|
|
19
19
|
failureTitle: 'Touch targets do not have sufficient size or spacing.',
|
|
20
20
|
/** Description of a Lighthouse audit that tells the user *why* they should try to pass. This is displayed after a user expands the section to see more. No character length limits. The last sentence starting with 'Learn' becomes link text to additional documentation. */
|
|
21
21
|
description: 'Touch targets with sufficient size and spacing help users who may have ' +
|
|
22
|
-
'difficulty targeting small controls activate the targets. ' +
|
|
22
|
+
'difficulty targeting small controls to activate the targets. ' +
|
|
23
23
|
'[Learn more about touch targets](https://dequeuniversity.com/rules/axe/4.7/target-size).',
|
|
24
24
|
};
|
|
25
25
|
|
|
@@ -229,8 +229,8 @@ class DuplicatedJavascript extends ByteEfficiencyAudit {
|
|
|
229
229
|
const headings = [
|
|
230
230
|
/* eslint-disable max-len */
|
|
231
231
|
{key: 'source', valueType: 'code', subItemsHeading: {key: 'url', valueType: 'url'}, label: str_(i18n.UIStrings.columnSource)},
|
|
232
|
-
{key: null, valueType: 'bytes', subItemsHeading: {key: 'sourceTransferBytes'}, granularity:
|
|
233
|
-
{key: 'wastedBytes', valueType: 'bytes', granularity:
|
|
232
|
+
{key: null, valueType: 'bytes', subItemsHeading: {key: 'sourceTransferBytes'}, granularity: 10, label: str_(i18n.UIStrings.columnTransferSize)},
|
|
233
|
+
{key: 'wastedBytes', valueType: 'bytes', granularity: 10, label: str_(i18n.UIStrings.columnWastedBytes)},
|
|
234
234
|
/* eslint-enable max-len */
|
|
235
235
|
];
|
|
236
236
|
|
|
@@ -2,12 +2,29 @@ export default UsesHTTP2Audit;
|
|
|
2
2
|
export type Simulator = import('../../lib/dependency-graph/simulator/simulator').Simulator;
|
|
3
3
|
export type Node = import('../../lib/dependency-graph/base-node.js').Node;
|
|
4
4
|
declare class UsesHTTP2Audit extends Audit {
|
|
5
|
+
/**
|
|
6
|
+
* Computes the estimated effect of all results being converted to http/2 on the provided graph.
|
|
7
|
+
*
|
|
8
|
+
* @param {Array<{url: string}>} results
|
|
9
|
+
* @param {Node} graph
|
|
10
|
+
* @param {Simulator} simulator
|
|
11
|
+
* @param {{label?: string}=} options
|
|
12
|
+
* @return {{savings: number, simulationBefore: LH.Gatherer.Simulation.Result, simulationAfter: LH.Gatherer.Simulation.Result}}
|
|
13
|
+
*/
|
|
14
|
+
static computeWasteWithGraph(results: Array<{
|
|
15
|
+
url: string;
|
|
16
|
+
}>, graph: Node, simulator: Simulator, options?: {
|
|
17
|
+
label?: string;
|
|
18
|
+
} | undefined): {
|
|
19
|
+
savings: number;
|
|
20
|
+
simulationBefore: LH.Gatherer.Simulation.Result;
|
|
21
|
+
simulationAfter: LH.Gatherer.Simulation.Result;
|
|
22
|
+
};
|
|
5
23
|
/**
|
|
6
24
|
* Computes the estimated effect all results being converted to use http/2, the max of:
|
|
7
25
|
*
|
|
8
26
|
* - end time of the last long task in the provided graph
|
|
9
27
|
* - end time of the last node in the graph
|
|
10
|
-
*
|
|
11
28
|
* @param {Array<{url: string}>} results
|
|
12
29
|
* @param {Node} graph
|
|
13
30
|
* @param {Simulator} simulator
|
|
@@ -21,6 +21,8 @@ import {NetworkRequest} from '../../lib/network-request.js';
|
|
|
21
21
|
import {NetworkRecords} from '../../computed/network-records.js';
|
|
22
22
|
import {LoadSimulator} from '../../computed/load-simulator.js';
|
|
23
23
|
import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
|
|
24
|
+
import {LanternLargestContentfulPaint} from '../../computed/metrics/lantern-largest-contentful-paint.js';
|
|
25
|
+
import {LanternFirstContentfulPaint} from '../../computed/metrics/lantern-first-contentful-paint.js';
|
|
24
26
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
25
27
|
|
|
26
28
|
const UIStrings = {
|
|
@@ -66,23 +68,23 @@ class UsesHTTP2Audit extends Audit {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/**
|
|
69
|
-
* Computes the estimated effect all results being converted to
|
|
70
|
-
*
|
|
71
|
-
* - end time of the last long task in the provided graph
|
|
72
|
-
* - end time of the last node in the graph
|
|
71
|
+
* Computes the estimated effect of all results being converted to http/2 on the provided graph.
|
|
73
72
|
*
|
|
74
73
|
* @param {Array<{url: string}>} results
|
|
75
74
|
* @param {Node} graph
|
|
76
75
|
* @param {Simulator} simulator
|
|
77
|
-
* @
|
|
76
|
+
* @param {{label?: string}=} options
|
|
77
|
+
* @return {{savings: number, simulationBefore: LH.Gatherer.Simulation.Result, simulationAfter: LH.Gatherer.Simulation.Result}}
|
|
78
78
|
*/
|
|
79
|
-
static
|
|
80
|
-
|
|
81
|
-
const
|
|
79
|
+
static computeWasteWithGraph(results, graph, simulator, options) {
|
|
80
|
+
options = Object.assign({label: ''}, options);
|
|
81
|
+
const beforeLabel = `${this.meta.id}-${options.label}-before`;
|
|
82
|
+
const afterLabel = `${this.meta.id}-${options.label}-after`;
|
|
82
83
|
const flexibleOrdering = true;
|
|
83
84
|
|
|
84
85
|
const urlsToChange = new Set(results.map(result => result.url));
|
|
85
|
-
const simulationBefore =
|
|
86
|
+
const simulationBefore =
|
|
87
|
+
simulator.simulate(graph, {label: beforeLabel, flexibleOrdering});
|
|
86
88
|
|
|
87
89
|
// Update all the protocols to reflect implementing our recommendations
|
|
88
90
|
/** @type {Map<string, string>} */
|
|
@@ -105,9 +107,36 @@ class UsesHTTP2Audit extends Audit {
|
|
|
105
107
|
node.record.protocol = originalProtocol;
|
|
106
108
|
});
|
|
107
109
|
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
+
const savings = simulationBefore.timeInMs - simulationAfter.timeInMs;
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
// Round waste to nearest 10ms
|
|
114
|
+
savings: Math.round(Math.max(savings, 0) / 10) * 10,
|
|
115
|
+
simulationBefore,
|
|
116
|
+
simulationAfter,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Computes the estimated effect all results being converted to use http/2, the max of:
|
|
122
|
+
*
|
|
123
|
+
* - end time of the last long task in the provided graph
|
|
124
|
+
* - end time of the last node in the graph
|
|
125
|
+
* @param {Array<{url: string}>} results
|
|
126
|
+
* @param {Node} graph
|
|
127
|
+
* @param {Simulator} simulator
|
|
128
|
+
* @return {number}
|
|
129
|
+
*/
|
|
130
|
+
static computeWasteWithTTIGraph(results, graph, simulator) {
|
|
131
|
+
const {savings: savingsOnOverallLoad, simulationBefore, simulationAfter} =
|
|
132
|
+
this.computeWasteWithGraph(results, graph, simulator, {
|
|
133
|
+
label: 'tti',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const savingsOnTTI =
|
|
137
|
+
LanternInteractive.getLastLongTaskEndTime(simulationBefore.nodeTimings) -
|
|
110
138
|
LanternInteractive.getLastLongTaskEndTime(simulationAfter.nodeTimings);
|
|
139
|
+
|
|
111
140
|
const savings = Math.max(savingsOnTTI, savingsOnOverallLoad);
|
|
112
141
|
|
|
113
142
|
// Round waste to nearest 10ms
|
|
@@ -237,9 +266,25 @@ class UsesHTTP2Audit extends Audit {
|
|
|
237
266
|
devtoolsLog,
|
|
238
267
|
settings,
|
|
239
268
|
};
|
|
240
|
-
const
|
|
269
|
+
const pageGraph = await PageDependencyGraph.request({trace, devtoolsLog, URL}, context);
|
|
241
270
|
const simulator = await LoadSimulator.request(simulatorOptions, context);
|
|
242
|
-
const
|
|
271
|
+
const metricComputationInput = Audit.makeMetricComputationDataInput(artifacts, context);
|
|
272
|
+
|
|
273
|
+
const {
|
|
274
|
+
pessimisticGraph: fcpGraph,
|
|
275
|
+
} = await LanternFirstContentfulPaint.request(metricComputationInput, context);
|
|
276
|
+
const {
|
|
277
|
+
pessimisticGraph: lcpGraph,
|
|
278
|
+
} = await LanternLargestContentfulPaint.request(metricComputationInput, context);
|
|
279
|
+
|
|
280
|
+
const wastedMsTti = UsesHTTP2Audit.computeWasteWithTTIGraph(
|
|
281
|
+
resources, pageGraph, simulator);
|
|
282
|
+
const wasteFcp =
|
|
283
|
+
UsesHTTP2Audit.computeWasteWithGraph(resources,
|
|
284
|
+
fcpGraph, simulator, {label: 'fcp'});
|
|
285
|
+
const wasteLcp =
|
|
286
|
+
UsesHTTP2Audit.computeWasteWithGraph(resources,
|
|
287
|
+
lcpGraph, simulator, {label: 'lcp'});
|
|
243
288
|
|
|
244
289
|
/** @type {LH.Audit.Details.Opportunity['headings']} */
|
|
245
290
|
const headings = [
|
|
@@ -248,14 +293,15 @@ class UsesHTTP2Audit extends Audit {
|
|
|
248
293
|
];
|
|
249
294
|
|
|
250
295
|
const details = Audit.makeOpportunityDetails(headings, resources,
|
|
251
|
-
{overallSavingsMs:
|
|
296
|
+
{overallSavingsMs: wastedMsTti});
|
|
252
297
|
|
|
253
298
|
return {
|
|
254
299
|
displayValue,
|
|
255
|
-
numericValue:
|
|
300
|
+
numericValue: wastedMsTti,
|
|
256
301
|
numericUnit: 'millisecond',
|
|
257
|
-
score: ByteEfficiencyAudit.scoreForWastedMs(
|
|
302
|
+
score: ByteEfficiencyAudit.scoreForWastedMs(wastedMsTti),
|
|
258
303
|
details,
|
|
304
|
+
metricSavings: {LCP: wasteLcp.savings, FCP: wasteFcp.savings},
|
|
259
305
|
};
|
|
260
306
|
}
|
|
261
307
|
}
|
|
@@ -59,10 +59,6 @@ export const UIStrings: {
|
|
|
59
59
|
'manifest-display-not-supported': string;
|
|
60
60
|
/** Error message explaining that the manifest could not be fetched, might be empty, or could not be parsed. */
|
|
61
61
|
'manifest-empty': string;
|
|
62
|
-
/** Error message explaining that no matching service worker was detected,
|
|
63
|
-
* and provides a suggestion to reload the page or check whether the scope of the service worker
|
|
64
|
-
* for the current page encloses the scope and start URL from the manifest. */
|
|
65
|
-
'no-matching-service-worker': string;
|
|
66
62
|
/**
|
|
67
63
|
* @description Error message explaining that the manifest does not contain a suitable icon.
|
|
68
64
|
* @example {192} value0
|
|
@@ -104,7 +100,7 @@ export const UIStrings: {
|
|
|
104
100
|
'manifest-location-changed': string;
|
|
105
101
|
/** Warning message explaining that the page does not work offline. */
|
|
106
102
|
'warn-not-offline-capable': string;
|
|
107
|
-
/** Error message explaining that Lighthouse failed while
|
|
103
|
+
/** Error message explaining that Lighthouse failed while checking if the page is installable, and directing the user to try again in a new Chrome. */
|
|
108
104
|
'protocol-timeout': string;
|
|
109
105
|
/** Message logged when the web app has been uninstalled o desktop, signalling that the install banner state is being reset. */
|
|
110
106
|
'pipeline-restarted': string;
|
|
@@ -44,11 +44,6 @@ const UIStrings = {
|
|
|
44
44
|
'manifest-display-not-supported': `Manifest 'display' property must be one of 'standalone', 'fullscreen', or 'minimal-ui'`,
|
|
45
45
|
/** Error message explaining that the manifest could not be fetched, might be empty, or could not be parsed. */
|
|
46
46
|
'manifest-empty': `Manifest could not be fetched, is empty, or could not be parsed`,
|
|
47
|
-
// TODO: This error was removed in M114, we can remove this message when it hits stable.
|
|
48
|
-
/** Error message explaining that no matching service worker was detected,
|
|
49
|
-
* and provides a suggestion to reload the page or check whether the scope of the service worker
|
|
50
|
-
* for the current page encloses the scope and start URL from the manifest. */
|
|
51
|
-
'no-matching-service-worker': `No matching service worker detected. You may need to reload the page, or check that the scope of the service worker for the current page encloses the scope and start URL from the manifest.`,
|
|
52
47
|
/**
|
|
53
48
|
* @description Error message explaining that the manifest does not contain a suitable icon.
|
|
54
49
|
* @example {192} value0
|
|
@@ -93,8 +88,8 @@ const UIStrings = {
|
|
|
93
88
|
'manifest-location-changed': `Manifest URL changed while the manifest was being fetched.`,
|
|
94
89
|
/** Warning message explaining that the page does not work offline. */
|
|
95
90
|
'warn-not-offline-capable': `Page does not work offline. The page will not be regarded as installable after Chrome 93, stable release August 2021.`,
|
|
96
|
-
/** Error message explaining that Lighthouse failed while
|
|
97
|
-
'protocol-timeout': `Lighthouse could not determine if
|
|
91
|
+
/** Error message explaining that Lighthouse failed while checking if the page is installable, and directing the user to try again in a new Chrome. */
|
|
92
|
+
'protocol-timeout': `Lighthouse could not determine if the page is installable. Please try with a newer version of Chrome.`,
|
|
98
93
|
/** Message logged when the web app has been uninstalled o desktop, signalling that the install banner state is being reset. */
|
|
99
94
|
'pipeline-restarted': 'PWA has been uninstalled and installability checks resetting.',
|
|
100
95
|
/**
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
export default LargestContentfulPaintElement;
|
|
2
2
|
declare class LargestContentfulPaintElement extends Audit {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Artifacts.MetricComputationDataInput} metricComputationData
|
|
5
|
-
* @param {LH.Audit.Context} context
|
|
6
|
-
* @return {Promise<number|undefined>}
|
|
7
|
-
*/
|
|
8
|
-
static getOptionalLCPMetric(metricComputationData: LH.Artifacts.MetricComputationDataInput, context: LH.Audit.Context): Promise<number | undefined>;
|
|
9
3
|
/**
|
|
10
4
|
* @param {LH.Artifacts} artifacts
|
|
11
5
|
* @return {LH.Audit.Details.Table|undefined}
|
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import log from 'lighthouse-logger';
|
|
8
|
+
|
|
7
9
|
import {Audit} from './audit.js';
|
|
8
10
|
import * as i18n from '../lib/i18n/i18n.js';
|
|
9
11
|
import {LargestContentfulPaint} from '../computed/metrics/largest-contentful-paint.js';
|
|
10
12
|
import {LCPBreakdown} from '../computed/metrics/lcp-breakdown.js';
|
|
13
|
+
import {Sentry} from '../lib/sentry.js';
|
|
11
14
|
|
|
12
15
|
const UIStrings = {
|
|
13
16
|
/** Descriptive title of a diagnostic audit that provides the element that was determined to be the Largest Contentful Paint. */
|
|
@@ -49,19 +52,6 @@ class LargestContentfulPaintElement extends Audit {
|
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
/**
|
|
53
|
-
* @param {LH.Artifacts.MetricComputationDataInput} metricComputationData
|
|
54
|
-
* @param {LH.Audit.Context} context
|
|
55
|
-
* @return {Promise<number|undefined>}
|
|
56
|
-
*/
|
|
57
|
-
static async getOptionalLCPMetric(metricComputationData, context) {
|
|
58
|
-
try {
|
|
59
|
-
const {timing: metricLcp} =
|
|
60
|
-
await LargestContentfulPaint.request(metricComputationData, context);
|
|
61
|
-
return metricLcp;
|
|
62
|
-
} catch {}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
55
|
/**
|
|
66
56
|
* @param {LH.Artifacts} artifacts
|
|
67
57
|
* @return {LH.Audit.Details.Table|undefined}
|
|
@@ -139,11 +129,19 @@ class LargestContentfulPaintElement extends Audit {
|
|
|
139
129
|
const items = [elementTable];
|
|
140
130
|
let displayValue;
|
|
141
131
|
|
|
142
|
-
|
|
143
|
-
|
|
132
|
+
try {
|
|
133
|
+
const {timing: metricLcp} =
|
|
134
|
+
await LargestContentfulPaint.request(metricComputationData, context);
|
|
144
135
|
displayValue = str_(i18n.UIStrings.ms, {timeInMs: metricLcp});
|
|
136
|
+
|
|
145
137
|
const phaseTable = await this.makePhaseTable(metricLcp, metricComputationData, context);
|
|
146
138
|
items.push(phaseTable);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
Sentry.captureException(err, {
|
|
141
|
+
tags: {audit: this.meta.id},
|
|
142
|
+
level: 'error',
|
|
143
|
+
});
|
|
144
|
+
log.error(this.meta.id, err.message);
|
|
147
145
|
}
|
|
148
146
|
|
|
149
147
|
const details = Audit.makeListDetails(items);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export default
|
|
1
|
+
export default InteractionToNextPaint;
|
|
2
2
|
/**
|
|
3
3
|
* @fileoverview This metric gives a high-percentile measure of responsiveness to input.
|
|
4
4
|
*/
|
|
5
|
-
declare class
|
|
5
|
+
declare class InteractionToNextPaint extends Audit {
|
|
6
6
|
/**
|
|
7
7
|
* @return {LH.Audit.ScoreOptions}
|
|
8
8
|
*/
|
|
@@ -18,4 +18,4 @@ export namespace UIStrings {
|
|
|
18
18
|
const description: string;
|
|
19
19
|
}
|
|
20
20
|
import { Audit } from '../audit.js';
|
|
21
|
-
//# sourceMappingURL=
|
|
21
|
+
//# sourceMappingURL=interaction-to-next-paint.d.ts.map
|
|
@@ -20,13 +20,13 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
|
20
20
|
/**
|
|
21
21
|
* @fileoverview This metric gives a high-percentile measure of responsiveness to input.
|
|
22
22
|
*/
|
|
23
|
-
class
|
|
23
|
+
class InteractionToNextPaint extends Audit {
|
|
24
24
|
/**
|
|
25
25
|
* @return {LH.Audit.Meta}
|
|
26
26
|
*/
|
|
27
27
|
static get meta() {
|
|
28
28
|
return {
|
|
29
|
-
id: '
|
|
29
|
+
id: 'interaction-to-next-paint',
|
|
30
30
|
title: str_(i18n.UIStrings.interactionToNextPaint),
|
|
31
31
|
description: str_(UIStrings.description),
|
|
32
32
|
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
|
|
@@ -84,5 +84,5 @@ class ExperimentalInteractionToNextPaint extends Audit {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export default
|
|
87
|
+
export default InteractionToNextPaint;
|
|
88
88
|
export {UIStrings};
|
|
@@ -14,6 +14,7 @@ import {LoadSimulator} from '../computed/load-simulator.js';
|
|
|
14
14
|
import {ProcessedNavigation} from '../computed/processed-navigation.js';
|
|
15
15
|
import {PageDependencyGraph} from '../computed/page-dependency-graph.js';
|
|
16
16
|
import {LanternLargestContentfulPaint} from '../computed/metrics/lantern-largest-contentful-paint.js';
|
|
17
|
+
import {LanternFirstContentfulPaint} from '../computed/metrics/lantern-first-contentful-paint.js';
|
|
17
18
|
|
|
18
19
|
// Preconnect establishes a "clean" socket. Chrome's socket manager will keep an unused socket
|
|
19
20
|
// around for 10s. Meaning, the time delta between processing preconnect a request should be <10s,
|
|
@@ -125,7 +126,8 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
125
126
|
const devtoolsLog = artifacts.devtoolsLogs[UsesRelPreconnectAudit.DEFAULT_PASS];
|
|
126
127
|
const settings = context.settings;
|
|
127
128
|
|
|
128
|
-
let
|
|
129
|
+
let maxWastedLcp = 0;
|
|
130
|
+
let maxWastedFcp = 0;
|
|
129
131
|
/** @type {Array<LH.IcuMessage>} */
|
|
130
132
|
const warnings = [];
|
|
131
133
|
|
|
@@ -144,7 +146,14 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
144
146
|
/** @type {Set<string>} */
|
|
145
147
|
const lcpGraphURLs = new Set();
|
|
146
148
|
lcpGraph.traverse(node => {
|
|
147
|
-
if (node.type === 'network'
|
|
149
|
+
if (node.type === 'network') lcpGraphURLs.add(node.record.url);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const fcpGraph =
|
|
153
|
+
await LanternFirstContentfulPaint.getPessimisticGraph(pageGraph, processedNavigation);
|
|
154
|
+
const fcpGraphURLs = new Set();
|
|
155
|
+
fcpGraph.traverse(node => {
|
|
156
|
+
if (node.type === 'network') fcpGraphURLs.add(node.record.url);
|
|
148
157
|
});
|
|
149
158
|
|
|
150
159
|
/** @type {Map<string, LH.Artifacts.NetworkRequest[]>} */
|
|
@@ -216,7 +225,11 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
216
225
|
return;
|
|
217
226
|
}
|
|
218
227
|
|
|
219
|
-
|
|
228
|
+
maxWastedLcp = Math.max(wastedMs, maxWastedLcp);
|
|
229
|
+
|
|
230
|
+
if (fcpGraphURLs.has(firstRecordOfOrigin.url)) {
|
|
231
|
+
maxWastedFcp = Math.max(wastedMs, maxWastedLcp);
|
|
232
|
+
}
|
|
220
233
|
results.push({
|
|
221
234
|
url: securityOrigin,
|
|
222
235
|
wastedMs: wastedMs,
|
|
@@ -240,6 +253,7 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
240
253
|
score: 1,
|
|
241
254
|
warnings: preconnectLinks.length >= 3 ?
|
|
242
255
|
[...warnings, str_(UIStrings.tooManyPreconnectLinksWarning)] : warnings,
|
|
256
|
+
metricSavings: {LCP: maxWastedLcp, FCP: maxWastedFcp},
|
|
243
257
|
};
|
|
244
258
|
}
|
|
245
259
|
|
|
@@ -250,17 +264,18 @@ class UsesRelPreconnectAudit extends Audit {
|
|
|
250
264
|
];
|
|
251
265
|
|
|
252
266
|
const details = Audit.makeOpportunityDetails(headings, results,
|
|
253
|
-
{overallSavingsMs:
|
|
267
|
+
{overallSavingsMs: maxWastedLcp, sortedBy: ['wastedMs']});
|
|
254
268
|
|
|
255
269
|
return {
|
|
256
|
-
score: ByteEfficiencyAudit.scoreForWastedMs(
|
|
257
|
-
numericValue:
|
|
270
|
+
score: ByteEfficiencyAudit.scoreForWastedMs(maxWastedLcp),
|
|
271
|
+
numericValue: maxWastedLcp,
|
|
258
272
|
numericUnit: 'millisecond',
|
|
259
|
-
displayValue:
|
|
260
|
-
str_(i18n.UIStrings.displayValueMsSavings, {wastedMs:
|
|
273
|
+
displayValue: maxWastedLcp ?
|
|
274
|
+
str_(i18n.UIStrings.displayValueMsSavings, {wastedMs: maxWastedLcp}) :
|
|
261
275
|
'',
|
|
262
276
|
warnings,
|
|
263
277
|
details,
|
|
278
|
+
metricSavings: {LCP: maxWastedLcp, FCP: maxWastedFcp},
|
|
264
279
|
};
|
|
265
280
|
}
|
|
266
281
|
}
|