lighthouse 12.8.2 → 13.0.0-dev.20251010
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/cli/cli-flags.js +1 -1
- package/cli/test/smokehouse/config/exclusions.js +0 -2
- package/cli/test/smokehouse/version-check.d.ts +1 -1
- package/core/audits/accessibility/accesskeys.js +3 -3
- package/core/audits/accessibility/aria-allowed-attr.js +3 -3
- package/core/audits/accessibility/aria-allowed-role.js +2 -1
- package/core/audits/accessibility/aria-command-name.js +1 -1
- package/core/audits/accessibility/aria-conditional-attr.js +1 -1
- package/core/audits/accessibility/aria-deprecated-role.js +1 -1
- package/core/audits/accessibility/aria-dialog-name.js +1 -1
- package/core/audits/accessibility/aria-hidden-body.js +3 -3
- package/core/audits/accessibility/aria-hidden-focus.js +3 -3
- package/core/audits/accessibility/aria-input-field-name.js +3 -3
- package/core/audits/accessibility/aria-meter-name.js +1 -1
- package/core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/core/audits/accessibility/aria-prohibited-attr.js +1 -1
- package/core/audits/accessibility/aria-required-attr.js +3 -3
- package/core/audits/accessibility/aria-required-children.js +3 -3
- package/core/audits/accessibility/aria-required-parent.js +3 -3
- package/core/audits/accessibility/aria-roles.js +3 -3
- package/core/audits/accessibility/aria-text.js +3 -3
- package/core/audits/accessibility/aria-toggle-field-name.js +3 -3
- package/core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/core/audits/accessibility/aria-valid-attr-value.js +3 -3
- package/core/audits/accessibility/aria-valid-attr.js +3 -3
- package/core/audits/accessibility/button-name.js +3 -3
- package/core/audits/accessibility/bypass.js +3 -3
- package/core/audits/accessibility/color-contrast.js +3 -3
- package/core/audits/accessibility/definition-list.js +3 -3
- package/core/audits/accessibility/dlitem.js +3 -3
- package/core/audits/accessibility/document-title.js +3 -3
- package/core/audits/accessibility/duplicate-id-aria.js +3 -3
- package/core/audits/accessibility/empty-heading.js +3 -3
- package/core/audits/accessibility/form-field-multiple-labels.js +3 -3
- package/core/audits/accessibility/frame-title.js +3 -3
- package/core/audits/accessibility/heading-order.js +3 -3
- package/core/audits/accessibility/html-has-lang.js +3 -3
- package/core/audits/accessibility/html-lang-valid.js +3 -3
- package/core/audits/accessibility/html-xml-lang-mismatch.js +3 -3
- package/core/audits/accessibility/identical-links-same-purpose.js +3 -3
- package/core/audits/accessibility/image-alt.js +3 -3
- package/core/audits/accessibility/image-redundant-alt.js +4 -3
- package/core/audits/accessibility/input-button-name.js +3 -3
- package/core/audits/accessibility/input-image-alt.js +3 -3
- package/core/audits/accessibility/label-content-name-mismatch.js +3 -3
- package/core/audits/accessibility/label.js +3 -3
- package/core/audits/accessibility/landmark-one-main.js +3 -4
- package/core/audits/accessibility/link-in-text-block.js +3 -3
- package/core/audits/accessibility/link-name.js +3 -3
- package/core/audits/accessibility/list.js +3 -3
- package/core/audits/accessibility/listitem.js +3 -3
- package/core/audits/accessibility/meta-refresh.js +3 -3
- package/core/audits/accessibility/meta-viewport.js +3 -3
- package/core/audits/accessibility/object-alt.js +3 -3
- package/core/audits/accessibility/select-name.js +3 -3
- package/core/audits/accessibility/skip-link.js +3 -3
- package/core/audits/accessibility/tabindex.js +3 -3
- package/core/audits/accessibility/table-duplicate-name.js +4 -3
- package/core/audits/accessibility/table-fake-caption.js +3 -3
- package/core/audits/accessibility/target-size.js +3 -3
- package/core/audits/accessibility/td-has-header.js +3 -3
- package/core/audits/accessibility/td-headers-attr.js +3 -3
- package/core/audits/accessibility/th-has-data-cells.js +3 -3
- package/core/audits/accessibility/valid-lang.js +3 -3
- package/core/audits/accessibility/video-caption.js +3 -3
- package/core/audits/audit.d.ts +0 -4
- package/core/audits/audit.js +2 -13
- package/core/audits/insights/cls-culprits-insight.js +1 -1
- package/core/audits/insights/dom-size-insight.js +11 -7
- package/core/audits/insights/font-display-insight.js +3 -1
- package/core/audits/insights/image-delivery-insight.js +4 -1
- package/core/audits/insights/insight-audit.d.ts +6 -4
- package/core/audits/insights/insight-audit.js +27 -8
- package/core/audits/insights/third-parties-insight.js +1 -1
- package/core/audits/layout-shifts.js +1 -1
- package/core/audits/predictive-perf.js +2 -2
- package/core/audits/seo/crawlable-anchors.js +2 -3
- package/core/audits/seo/manual/structured-data.js +1 -1
- package/core/audits/server-response-time.d.ts +0 -5
- package/core/audits/server-response-time.js +12 -26
- package/core/computed/metrics/cumulative-layout-shift.js +2 -2
- package/core/computed/metrics/lantern-metric.js +3 -3
- package/core/computed/metrics/lcp-breakdown.d.ts +10 -5
- package/core/computed/metrics/lcp-breakdown.js +50 -22
- package/core/computed/metrics/time-to-first-byte.js +33 -10
- package/core/computed/metrics/timing-summary.js +3 -2
- package/core/computed/page-dependency-graph.js +1 -1
- package/core/computed/trace-engine-result.js +2 -2
- package/core/config/default-config.js +110 -152
- package/core/config/experimental-config.js +1 -32
- package/core/config/filters.js +6 -9
- package/core/config/lr-desktop-config.js +0 -1
- package/core/config/lr-mobile-config.js +0 -1
- package/core/gather/driver/target-manager.d.ts +1 -1
- package/core/gather/driver.d.ts +1 -1
- package/core/gather/gatherers/anchor-elements.js +8 -24
- package/core/gather/gatherers/image-elements.js +32 -6
- package/core/gather/gatherers/inspector-issues.js +1 -28
- package/core/gather/gatherers/trace-elements.d.ts +2 -11
- package/core/gather/gatherers/trace-elements.js +9 -39
- package/core/gather/navigation-runner.js +0 -3
- package/core/gather/session.d.ts +1 -1
- package/core/lib/asset-saver.d.ts +2 -2
- package/core/lib/asset-saver.js +33 -43
- package/core/lib/bf-cache-strings.js +10 -9
- package/core/lib/deprecations-strings.js +5 -5
- package/core/lib/emulation.d.ts +10 -0
- package/core/lib/emulation.js +21 -6
- package/core/lib/legacy-javascript/legacy-javascript.js +4 -11
- package/core/lib/network-request.d.ts +0 -7
- package/core/lib/network-request.js +0 -16
- package/core/lib/proto-preprocessor.js +10 -25
- package/core/runner.js +1 -8
- package/core/scoring.js +1 -1
- package/dist/report/bundle.esm.js +10 -49
- package/dist/report/flow.js +12 -51
- package/dist/report/standalone.js +11 -50
- package/flow-report/src/i18n/i18n.d.ts +4 -6
- package/package.json +16 -19
- package/readme.md +2 -2
- package/report/assets/styles.css +0 -39
- package/report/renderer/api.js +0 -1
- package/report/renderer/category-renderer.js +6 -0
- package/report/renderer/components.js +1 -1
- package/report/renderer/details-renderer.d.ts +1 -2
- package/report/renderer/details-renderer.js +0 -1
- package/report/renderer/dom.d.ts +0 -13
- package/report/renderer/dom.js +0 -38
- package/report/renderer/performance-category-renderer.d.ts +0 -26
- package/report/renderer/performance-category-renderer.js +10 -142
- package/report/renderer/report-ui-features.d.ts +0 -1
- package/report/renderer/report-ui-features.js +2 -13
- package/report/renderer/report-utils.d.ts +2 -3
- package/report/renderer/report-utils.js +4 -6
- package/report/types/report-renderer.d.ts +0 -6
- package/shared/localization/locales/ar-XB.json +107 -455
- package/shared/localization/locales/ar.json +107 -455
- package/shared/localization/locales/bg.json +96 -444
- package/shared/localization/locales/ca.json +96 -444
- package/shared/localization/locales/cs.json +96 -444
- package/shared/localization/locales/da.json +96 -444
- package/shared/localization/locales/de.json +96 -444
- package/shared/localization/locales/el.json +96 -444
- package/shared/localization/locales/en-GB.json +96 -444
- package/shared/localization/locales/en-US.json +116 -467
- package/shared/localization/locales/en-XA.json +93 -441
- package/shared/localization/locales/en-XL.json +116 -467
- package/shared/localization/locales/es-419.json +96 -444
- package/shared/localization/locales/es.json +96 -444
- package/shared/localization/locales/fi.json +96 -444
- package/shared/localization/locales/fil.json +96 -444
- package/shared/localization/locales/fr.json +96 -444
- package/shared/localization/locales/he.json +118 -466
- package/shared/localization/locales/hi.json +96 -444
- package/shared/localization/locales/hr.json +100 -448
- package/shared/localization/locales/hu.json +96 -444
- package/shared/localization/locales/id.json +96 -444
- package/shared/localization/locales/it.json +96 -444
- package/shared/localization/locales/ja.json +96 -444
- package/shared/localization/locales/ko.json +97 -445
- package/shared/localization/locales/lt.json +96 -444
- package/shared/localization/locales/lv.json +97 -445
- package/shared/localization/locales/nl.json +96 -444
- package/shared/localization/locales/no.json +96 -444
- package/shared/localization/locales/pl.json +96 -444
- package/shared/localization/locales/pt-PT.json +96 -444
- package/shared/localization/locales/pt.json +97 -445
- package/shared/localization/locales/ro.json +97 -445
- package/shared/localization/locales/ru.json +96 -444
- package/shared/localization/locales/sk.json +96 -444
- package/shared/localization/locales/sl.json +96 -444
- package/shared/localization/locales/sr-Latn.json +96 -444
- package/shared/localization/locales/sr.json +96 -444
- package/shared/localization/locales/sv.json +96 -444
- package/shared/localization/locales/ta.json +96 -444
- package/shared/localization/locales/te.json +97 -445
- package/shared/localization/locales/th.json +96 -444
- package/shared/localization/locales/tr.json +96 -444
- package/shared/localization/locales/uk.json +96 -444
- package/shared/localization/locales/vi.json +96 -444
- package/shared/localization/locales/zh-HK.json +96 -444
- package/shared/localization/locales/zh-TW.json +97 -445
- package/shared/localization/locales/zh.json +96 -444
- package/shared/localization/locales.d.ts +2 -0
- package/shared/localization/locales.js +130 -139
- package/shared/tsconfig.json +2 -0
- package/tsconfig-base.json +2 -2
- package/tsconfig.json +1 -4
- package/types/artifacts.d.ts +6 -81
- package/types/audit.d.ts +1 -1
- package/types/lhr/settings.d.ts +1 -1
- package/core/audits/byte-efficiency/duplicated-javascript.d.ts +0 -45
- package/core/audits/byte-efficiency/duplicated-javascript.js +0 -223
- package/core/audits/byte-efficiency/efficient-animated-content.d.ts +0 -22
- package/core/audits/byte-efficiency/efficient-animated-content.js +0 -93
- package/core/audits/byte-efficiency/legacy-javascript.d.ts +0 -28
- package/core/audits/byte-efficiency/legacy-javascript.js +0 -144
- package/core/audits/byte-efficiency/modern-image-formats.d.ts +0 -38
- package/core/audits/byte-efficiency/modern-image-formats.js +0 -187
- package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -63
- package/core/audits/byte-efficiency/offscreen-images.js +0 -240
- package/core/audits/byte-efficiency/render-blocking-resources.d.ts +0 -53
- package/core/audits/byte-efficiency/render-blocking-resources.js +0 -312
- package/core/audits/byte-efficiency/uses-long-cache-ttl.d.ts +0 -59
- package/core/audits/byte-efficiency/uses-long-cache-ttl.js +0 -293
- package/core/audits/byte-efficiency/uses-optimized-images.d.ts +0 -33
- package/core/audits/byte-efficiency/uses-optimized-images.js +0 -146
- package/core/audits/byte-efficiency/uses-responsive-images-snapshot.d.ts +0 -16
- package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +0 -106
- package/core/audits/byte-efficiency/uses-responsive-images.d.ts +0 -44
- package/core/audits/byte-efficiency/uses-responsive-images.js +0 -202
- package/core/audits/byte-efficiency/uses-text-compression.d.ts +0 -14
- package/core/audits/byte-efficiency/uses-text-compression.js +0 -108
- package/core/audits/critical-request-chains.d.ts +0 -44
- package/core/audits/critical-request-chains.js +0 -221
- package/core/audits/dobetterweb/dom-size.d.ts +0 -32
- package/core/audits/dobetterweb/dom-size.js +0 -182
- package/core/audits/dobetterweb/no-document-write.d.ts +0 -16
- package/core/audits/dobetterweb/no-document-write.js +0 -86
- package/core/audits/dobetterweb/uses-http2.d.ts +0 -72
- package/core/audits/dobetterweb/uses-http2.js +0 -276
- package/core/audits/dobetterweb/uses-passive-event-listeners.d.ts +0 -16
- package/core/audits/dobetterweb/uses-passive-event-listeners.js +0 -69
- package/core/audits/font-display.d.ts +0 -32
- package/core/audits/font-display.js +0 -195
- package/core/audits/largest-contentful-paint-element.d.ts +0 -34
- package/core/audits/largest-contentful-paint-element.js +0 -181
- package/core/audits/lcp-lazy-loaded.d.ts +0 -22
- package/core/audits/lcp-lazy-loaded.js +0 -115
- package/core/audits/metrics/first-meaningful-paint.d.ts +0 -12
- package/core/audits/metrics/first-meaningful-paint.js +0 -47
- package/core/audits/preload-fonts.d.ts +0 -25
- package/core/audits/preload-fonts.js +0 -97
- package/core/audits/prioritize-lcp-image.d.ts +0 -74
- package/core/audits/prioritize-lcp-image.js +0 -297
- package/core/audits/seo/font-size.d.ts +0 -24
- package/core/audits/seo/font-size.js +0 -344
- package/core/audits/third-party-facades.d.ts +0 -41
- package/core/audits/third-party-facades.js +0 -234
- package/core/audits/third-party-summary.d.ts +0 -78
- package/core/audits/third-party-summary.js +0 -236
- package/core/audits/uses-rel-preconnect.d.ts +0 -37
- package/core/audits/uses-rel-preconnect.js +0 -286
- package/core/audits/uses-rel-preload.d.ts +0 -57
- package/core/audits/uses-rel-preload.js +0 -263
- package/core/audits/viewport.d.ts +0 -17
- package/core/audits/viewport.js +0 -87
- package/core/audits/work-during-interaction.d.ts +0 -81
- package/core/audits/work-during-interaction.js +0 -287
- package/core/computed/critical-request-chains.d.ts +0 -42
- package/core/computed/critical-request-chains.js +0 -143
- package/core/computed/viewport-meta.d.ts +0 -37
- package/core/computed/viewport-meta.js +0 -71
- package/core/gather/gatherers/cache-contents.d.ts +0 -11
- package/core/gather/gatherers/cache-contents.js +0 -56
- package/core/gather/gatherers/devtools-log-compat.d.ts +0 -13
- package/core/gather/gatherers/devtools-log-compat.js +0 -35
- package/core/gather/gatherers/dobetterweb/domstats.d.ts +0 -10
- package/core/gather/gatherers/dobetterweb/domstats.js +0 -102
- package/core/gather/gatherers/dobetterweb/optimized-images.d.ts +0 -48
- package/core/gather/gatherers/dobetterweb/optimized-images.js +0 -169
- package/core/gather/gatherers/dobetterweb/response-compression.d.ts +0 -23
- package/core/gather/gatherers/dobetterweb/response-compression.js +0 -136
- package/core/gather/gatherers/seo/font-size.d.ts +0 -131
- package/core/gather/gatherers/seo/font-size.js +0 -347
- package/core/gather/gatherers/trace-compat.d.ts +0 -13
- package/core/gather/gatherers/trace-compat.js +0 -35
- package/types/internal/metaviewport-parser.d.ts +0 -13
- package/types/internal/parse-cache-control.d.ts +0 -20
|
@@ -13,15 +13,15 @@ import AxeAudit from './axe-audit.js';
|
|
|
13
13
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
14
|
|
|
15
15
|
const UIStrings = {
|
|
16
|
-
/** Title of an
|
|
16
|
+
/** Title of an accessibility audit that evaluates if all large table elements use the headers HTML attribute. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
17
|
title: '`<td>` elements in a large `<table>` have one or more table headers.',
|
|
18
|
-
/** Title of an
|
|
18
|
+
/** Title of an accessibility audit that evaluates if all large table elements use the headers HTML attribute. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
19
|
failureTitle: '`<td>` elements in a large `<table>` do not have table headers.',
|
|
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: 'Screen readers have features to make navigating tables easier. Ensuring ' +
|
|
22
22
|
'that `<td>` elements in a large table (3 or more cells in width and height) have an ' +
|
|
23
23
|
'associated table header may improve the experience for screen reader users. ' +
|
|
24
|
-
'[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.
|
|
24
|
+
'[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.11/td-has-header).',
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -14,17 +14,17 @@ import AxeAudit from './axe-audit.js';
|
|
|
14
14
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
15
15
|
|
|
16
16
|
const UIStrings = {
|
|
17
|
-
/** Title of an
|
|
17
|
+
/** Title of an accessibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to header cells within the same table. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
18
18
|
title: 'Cells in a `<table>` element that use the `[headers]` attribute refer ' +
|
|
19
19
|
'to table cells within the same table.',
|
|
20
|
-
/** Title of an
|
|
20
|
+
/** Title of an accessibility audit that evaluates if all table cell elements in a table that use the headers HTML attribute use it correctly to refer to header cells within the same table. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
21
21
|
failureTitle: 'Cells in a `<table>` element that use the `[headers]` attribute refer ' +
|
|
22
22
|
'to an element `id` not found within the same table.',
|
|
23
23
|
/** 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. */
|
|
24
24
|
description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
|
|
25
25
|
'`<td>` cells using the `[headers]` attribute only refer to other cells in the same ' +
|
|
26
26
|
'table may improve the experience for screen reader users. ' +
|
|
27
|
-
'[Learn more about the `headers` attribute](https://dequeuniversity.com/rules/axe/4.
|
|
27
|
+
'[Learn more about the `headers` attribute](https://dequeuniversity.com/rules/axe/4.11/td-headers-attr).',
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -13,17 +13,17 @@ import AxeAudit from './axe-audit.js';
|
|
|
13
13
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
14
|
|
|
15
15
|
const UIStrings = {
|
|
16
|
-
/** Title of an
|
|
16
|
+
/** Title of an accessibility audit that evaluates if all table header elements have children. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
17
|
title: '`<th>` elements and elements with `[role="columnheader"/"rowheader"]` have ' +
|
|
18
18
|
'data cells they describe.',
|
|
19
|
-
/** Title of an
|
|
19
|
+
/** Title of an accessibility audit that evaluates if all table header elements have children. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
20
20
|
failureTitle: '`<th>` elements and elements with ' +
|
|
21
21
|
'`[role="columnheader"/"rowheader"]` do not have data cells they describe.',
|
|
22
22
|
/** 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. */
|
|
23
23
|
description: 'Screen readers have features to make navigating tables easier. Ensuring ' +
|
|
24
24
|
'table headers always refer to some set of cells may improve the experience for screen ' +
|
|
25
25
|
'reader users. ' +
|
|
26
|
-
'[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.
|
|
26
|
+
'[Learn more about table headers](https://dequeuniversity.com/rules/axe/4.11/th-has-data-cells).',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -13,14 +13,14 @@ import AxeAudit from './axe-audit.js';
|
|
|
13
13
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
14
|
|
|
15
15
|
const UIStrings = {
|
|
16
|
-
/** Title of an
|
|
16
|
+
/** Title of an accessibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
17
|
title: '`[lang]` attributes have a valid value',
|
|
18
|
-
/** Title of an
|
|
18
|
+
/** Title of an accessibility audit that evaluates if all lang HTML attributes are valid BCP 47 languages. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
19
|
failureTitle: '`[lang]` attributes do not have a valid value',
|
|
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: 'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) ' +
|
|
22
22
|
'on elements helps ensure that text is pronounced correctly by a screen reader. ' +
|
|
23
|
-
'[Learn how to use the `lang` attribute](https://dequeuniversity.com/rules/axe/4.
|
|
23
|
+
'[Learn how to use the `lang` attribute](https://dequeuniversity.com/rules/axe/4.11/valid-lang).',
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
@@ -13,15 +13,15 @@ import AxeAudit from './axe-audit.js';
|
|
|
13
13
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
14
14
|
|
|
15
15
|
const UIStrings = {
|
|
16
|
-
/** Title of an
|
|
16
|
+
/** Title of an accessibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the successful state and is shown to users when no user action is required. */
|
|
17
17
|
title: '`<video>` elements contain a `<track>` element with `[kind="captions"]`',
|
|
18
|
-
/** Title of an
|
|
18
|
+
/** Title of an accessibility audit that evaluates if all video elements contain a child track element that has captions describing their audio. This title is descriptive of the failing state and is shown to users when there is a failure that needs to be addressed. */
|
|
19
19
|
failureTitle: '`<video>` elements do not contain a `<track>` element ' +
|
|
20
20
|
'with `[kind="captions"]`.',
|
|
21
21
|
/** 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. */
|
|
22
22
|
description: 'When a video provides a caption it is easier for deaf and hearing impaired ' +
|
|
23
23
|
'users to access its information. ' +
|
|
24
|
-
'[Learn more about video captions](https://dequeuniversity.com/rules/axe/4.
|
|
24
|
+
'[Learn more about video captions](https://dequeuniversity.com/rules/axe/4.11/video-caption).',
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
package/core/audits/audit.d.ts
CHANGED
|
@@ -13,10 +13,6 @@ export type OpportunityOptions = {
|
|
|
13
13
|
isEntityGrouped?: LH.Audit.Details.Opportunity["isEntityGrouped"] | undefined;
|
|
14
14
|
};
|
|
15
15
|
export class Audit {
|
|
16
|
-
/**
|
|
17
|
-
* @return {string}
|
|
18
|
-
*/
|
|
19
|
-
static get DEFAULT_PASS(): string;
|
|
20
16
|
/**
|
|
21
17
|
* @return {LH.Audit.ScoreDisplayModes}
|
|
22
18
|
*/
|
package/core/audits/audit.js
CHANGED
|
@@ -8,8 +8,6 @@ import * as LH from '../../types/lh.js';
|
|
|
8
8
|
import {isUnderTest} from '../lib/lh-env.js';
|
|
9
9
|
import {Util} from '../../shared/util.js';
|
|
10
10
|
|
|
11
|
-
const DEFAULT_PASS = 'defaultPass';
|
|
12
|
-
|
|
13
11
|
/** @type {Record<keyof LH.Audit.ProductMetricSavings, number>} */
|
|
14
12
|
const METRIC_SAVINGS_PRECISION = {
|
|
15
13
|
FCP: 50,
|
|
@@ -45,14 +43,6 @@ const METRIC_SAVINGS_PRECISION = {
|
|
|
45
43
|
const clampTo2Decimals = val => Math.round(val * 100) / 100;
|
|
46
44
|
|
|
47
45
|
class Audit {
|
|
48
|
-
/**
|
|
49
|
-
* @return {string}
|
|
50
|
-
*/
|
|
51
|
-
static get DEFAULT_PASS() {
|
|
52
|
-
// TODO(v13): remove.
|
|
53
|
-
return DEFAULT_PASS;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
46
|
/**
|
|
57
47
|
* @return {LH.Audit.ScoreDisplayModes}
|
|
58
48
|
*/
|
|
@@ -494,7 +484,6 @@ class Audit {
|
|
|
494
484
|
|
|
495
485
|
details: product.details,
|
|
496
486
|
guidanceLevel: audit.meta.guidanceLevel,
|
|
497
|
-
replacesAudits: audit.meta.replacesAudits,
|
|
498
487
|
};
|
|
499
488
|
}
|
|
500
489
|
|
|
@@ -504,8 +493,8 @@ class Audit {
|
|
|
504
493
|
* @returns {LH.Artifacts.MetricComputationDataInput}
|
|
505
494
|
*/
|
|
506
495
|
static makeMetricComputationDataInput(artifacts, context) {
|
|
507
|
-
const trace = artifacts.Trace
|
|
508
|
-
const devtoolsLog = artifacts.DevtoolsLog
|
|
496
|
+
const trace = artifacts.Trace;
|
|
497
|
+
const devtoolsLog = artifacts.DevtoolsLog;
|
|
509
498
|
const gatherContext = artifacts.GatherContext;
|
|
510
499
|
const {URL, SourceMaps} = artifacts;
|
|
511
500
|
// eslint-disable-next-line max-len
|
|
@@ -38,7 +38,7 @@ class CLSCulpritsInsight extends Audit {
|
|
|
38
38
|
description: insightStr_(InsightUIStrings.description),
|
|
39
39
|
guidanceLevel: 3,
|
|
40
40
|
requiredArtifacts: ['Trace', 'TraceElements', 'SourceMaps'],
|
|
41
|
-
replacesAudits: ['layout-shifts'
|
|
41
|
+
replacesAudits: ['layout-shifts'],
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -59,21 +59,21 @@ class DOMSizeInsight extends Audit {
|
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
|
-
statistic: str_(UIStrings.
|
|
63
|
-
node: makeNodeItemForNodeId(artifacts.TraceElements,
|
|
62
|
+
statistic: str_(UIStrings.maxDOMDepth),
|
|
63
|
+
node: makeNodeItemForNodeId(artifacts.TraceElements, maxDepth.nodeId),
|
|
64
64
|
value: {
|
|
65
65
|
type: 'numeric',
|
|
66
66
|
granularity: 1,
|
|
67
|
-
value:
|
|
67
|
+
value: maxDepth.depth,
|
|
68
68
|
},
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
statistic: str_(UIStrings.
|
|
72
|
-
node: makeNodeItemForNodeId(artifacts.TraceElements,
|
|
71
|
+
statistic: str_(UIStrings.maxChildren),
|
|
72
|
+
node: makeNodeItemForNodeId(artifacts.TraceElements, maxChildren.nodeId),
|
|
73
73
|
value: {
|
|
74
74
|
type: 'numeric',
|
|
75
75
|
granularity: 1,
|
|
76
|
-
value:
|
|
76
|
+
value: maxChildren.numChildren,
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
79
|
];
|
|
@@ -85,7 +85,11 @@ class DOMSizeInsight extends Audit {
|
|
|
85
85
|
maxChildren: maxChildren.numChildren,
|
|
86
86
|
maxDepth: maxDepth.depth,
|
|
87
87
|
};
|
|
88
|
-
return
|
|
88
|
+
return {
|
|
89
|
+
details,
|
|
90
|
+
numericValue: totalElements,
|
|
91
|
+
numericUnit: 'element',
|
|
92
|
+
};
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
95
|
}
|
|
@@ -46,7 +46,9 @@ class FontDisplayInsight extends Audit {
|
|
|
46
46
|
url: font.request.args.data.url,
|
|
47
47
|
wastedMs: font.wastedTime,
|
|
48
48
|
}));
|
|
49
|
-
|
|
49
|
+
const details = Audit.makeTableDetails(headings, items);
|
|
50
|
+
details.skipSumming = ['wastedMs'];
|
|
51
|
+
return details;
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -9,7 +9,7 @@ import {UIStrings} from '@paulirish/trace_engine/models/trace/insights/ImageDeli
|
|
|
9
9
|
|
|
10
10
|
import {Audit} from '../audit.js';
|
|
11
11
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
12
|
-
import {adaptInsightToAuditProduct} from './insight-audit.js';
|
|
12
|
+
import {adaptInsightToAuditProduct, makeNodeItemForNodeId} from './insight-audit.js';
|
|
13
13
|
import {TraceEngineResult} from '../../computed/trace-engine-result.js';
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line max-len
|
|
@@ -49,6 +49,7 @@ class ImageDeliveryInsight extends Audit {
|
|
|
49
49
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
50
50
|
const headings = [
|
|
51
51
|
/* eslint-disable max-len */
|
|
52
|
+
{key: 'node', valueType: 'node', label: ''},
|
|
52
53
|
{key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL), subItemsHeading: {key: 'reason', valueType: 'text'}},
|
|
53
54
|
{key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnResourceSize)},
|
|
54
55
|
{key: 'wastedBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnWastedBytes), subItemsHeading: {key: 'wastedBytes', valueType: 'bytes'}},
|
|
@@ -57,6 +58,8 @@ class ImageDeliveryInsight extends Audit {
|
|
|
57
58
|
|
|
58
59
|
/** @type {LH.Audit.Details.Table['items']} */
|
|
59
60
|
const items = insight.optimizableImages.map(image => ({
|
|
61
|
+
node:
|
|
62
|
+
makeNodeItemForNodeId(artifacts.TraceElements, image.largestImagePaint.args.data.nodeId),
|
|
60
63
|
url: image.request.args.data.url,
|
|
61
64
|
totalBytes: image.request.args.data.decodedBodyLength,
|
|
62
65
|
wastedBytes: image.byteSavings,
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
export type CreateDetailsExtras = {
|
|
2
2
|
insights: import("@paulirish/trace_engine/models/trace/insights/types.js").InsightSet;
|
|
3
|
-
|
|
3
|
+
data: LH.Artifacts.TraceEngineResult["data"];
|
|
4
4
|
};
|
|
5
5
|
/**
|
|
6
6
|
* @typedef CreateDetailsExtras
|
|
7
7
|
* @property {import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet} insights
|
|
8
|
-
* @property {LH.Artifacts.TraceEngineResult['
|
|
8
|
+
* @property {LH.Artifacts.TraceEngineResult['data']} data
|
|
9
9
|
*/
|
|
10
10
|
/**
|
|
11
11
|
* @param {LH.Artifacts} artifacts
|
|
12
12
|
* @param {LH.Audit.Context} context
|
|
13
13
|
* @param {T} insightName
|
|
14
|
-
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings
|
|
14
|
+
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings?: Array<string | LH.IcuMessage>, numericValue?: number, numericUnit?: LH.Audit.NumericProduct['numericUnit']}|LH.Audit.Details|undefined} createDetails
|
|
15
15
|
* @template {keyof import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModelsType} T
|
|
16
16
|
* @return {Promise<LH.Audit.Product>}
|
|
17
17
|
*/
|
|
18
18
|
export function adaptInsightToAuditProduct<T extends keyof import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModelsType>(artifacts: LH.Artifacts, context: LH.Audit.Context, insightName: T, createDetails: (insight: import("@paulirish/trace_engine/models/trace/insights/types.js").InsightModels[T], extras: CreateDetailsExtras) => {
|
|
19
19
|
details: LH.Audit.Details;
|
|
20
|
-
warnings
|
|
20
|
+
warnings?: Array<string | LH.IcuMessage>;
|
|
21
|
+
numericValue?: number;
|
|
22
|
+
numericUnit?: LH.Audit.NumericProduct["numericUnit"];
|
|
21
23
|
} | LH.Audit.Details | undefined): Promise<LH.Audit.Product>;
|
|
22
24
|
/**
|
|
23
25
|
* @param {LH.Artifacts.TraceElement[]} traceElements
|
|
@@ -16,7 +16,7 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, {});
|
|
|
16
16
|
/**
|
|
17
17
|
* @param {LH.Artifacts} artifacts
|
|
18
18
|
* @param {LH.Audit.Context} context
|
|
19
|
-
* @return {Promise<{insights: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined,
|
|
19
|
+
* @return {Promise<{insights: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet|undefined, data: LH.Artifacts.TraceEngineResult['data']}>}
|
|
20
20
|
*/
|
|
21
21
|
async function getInsightSet(artifacts, context) {
|
|
22
22
|
const settings = context.settings;
|
|
@@ -29,25 +29,25 @@ async function getInsightSet(artifacts, context) {
|
|
|
29
29
|
const key = navigationId ?? NO_NAVIGATION;
|
|
30
30
|
const insights = traceEngineResult.insights.get(key);
|
|
31
31
|
|
|
32
|
-
return {insights,
|
|
32
|
+
return {insights, data: traceEngineResult.data};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* @typedef CreateDetailsExtras
|
|
37
37
|
* @property {import('@paulirish/trace_engine/models/trace/insights/types.js').InsightSet} insights
|
|
38
|
-
* @property {LH.Artifacts.TraceEngineResult['
|
|
38
|
+
* @property {LH.Artifacts.TraceEngineResult['data']} data
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* @param {LH.Artifacts} artifacts
|
|
43
43
|
* @param {LH.Audit.Context} context
|
|
44
44
|
* @param {T} insightName
|
|
45
|
-
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings
|
|
45
|
+
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings?: Array<string | LH.IcuMessage>, numericValue?: number, numericUnit?: LH.Audit.NumericProduct['numericUnit']}|LH.Audit.Details|undefined} createDetails
|
|
46
46
|
* @template {keyof import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModelsType} T
|
|
47
47
|
* @return {Promise<LH.Audit.Product>}
|
|
48
48
|
*/
|
|
49
49
|
async function adaptInsightToAuditProduct(artifacts, context, insightName, createDetails) {
|
|
50
|
-
const {
|
|
50
|
+
const {data, insights} = await getInsightSet(artifacts, context);
|
|
51
51
|
if (!insights) {
|
|
52
52
|
return {
|
|
53
53
|
scoreDisplayMode: Audit.SCORING_MODES.NOT_APPLICABLE,
|
|
@@ -65,16 +65,22 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const cbResult = createDetails(insight, {
|
|
68
|
-
|
|
68
|
+
data,
|
|
69
69
|
insights,
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
const warnings = [...insight.warnings ?? []];
|
|
73
|
+
/** @type {number|undefined} */
|
|
74
|
+
let numericValue;
|
|
75
|
+
/** @type {LH.Audit.NumericProduct['numericUnit']|undefined} */
|
|
76
|
+
let numericUnit;
|
|
73
77
|
|
|
74
78
|
let details;
|
|
75
|
-
if (cbResult && '
|
|
79
|
+
if (cbResult && 'details' in cbResult) {
|
|
76
80
|
details = cbResult.details;
|
|
77
|
-
warnings.push(...cbResult.warnings);
|
|
81
|
+
if (cbResult.warnings) warnings.push(...cbResult.warnings);
|
|
82
|
+
numericValue = cbResult.numericValue;
|
|
83
|
+
numericUnit = cbResult.numericUnit;
|
|
78
84
|
} else {
|
|
79
85
|
details = cbResult;
|
|
80
86
|
}
|
|
@@ -163,6 +169,19 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
|
|
|
163
169
|
scoreDisplayMode = Audit.SCORING_MODES.INFORMATIVE;
|
|
164
170
|
}
|
|
165
171
|
|
|
172
|
+
if (numericValue !== undefined && numericUnit !== undefined) {
|
|
173
|
+
return {
|
|
174
|
+
scoreDisplayMode,
|
|
175
|
+
score,
|
|
176
|
+
numericValue,
|
|
177
|
+
numericUnit,
|
|
178
|
+
metricSavings,
|
|
179
|
+
warnings: warnings.length ? warnings : undefined,
|
|
180
|
+
displayValue,
|
|
181
|
+
details,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
166
185
|
return {
|
|
167
186
|
scoreDisplayMode,
|
|
168
187
|
score,
|
|
@@ -61,7 +61,7 @@ class ThirdPartiesInsight extends Audit {
|
|
|
61
61
|
*/
|
|
62
62
|
static async audit(artifacts, context) {
|
|
63
63
|
return adaptInsightToAuditProduct(artifacts, context, 'ThirdParties', (insight, extras) => {
|
|
64
|
-
const urlSummaries = summarizeByURL(extras.
|
|
64
|
+
const urlSummaries = summarizeByURL(extras.data, extras.insights.bounds);
|
|
65
65
|
|
|
66
66
|
const thirdPartySummaries = insight.entitySummaries
|
|
67
67
|
.filter(summary => summary.entity !== insight.firstPartyEntity || null)
|
|
@@ -62,7 +62,7 @@ class LayoutShifts extends Audit {
|
|
|
62
62
|
const SourceMaps = artifacts.SourceMaps;
|
|
63
63
|
const traceEngineResult =
|
|
64
64
|
await TraceEngineResult.request({trace, settings, SourceMaps}, context);
|
|
65
|
-
const clusters = traceEngineResult.
|
|
65
|
+
const clusters = traceEngineResult.data.LayoutShifts.clusters ?? [];
|
|
66
66
|
const {cumulativeLayoutShift: clsSavings, impactByNodeId} =
|
|
67
67
|
await CumulativeLayoutShiftComputed.request(trace, context);
|
|
68
68
|
const traceElements = artifacts.TraceElements
|
|
@@ -76,8 +76,8 @@ class PredictivePerf extends Audit {
|
|
|
76
76
|
pessimisticLCP: lcp.pessimisticEstimate.timeInMs,
|
|
77
77
|
|
|
78
78
|
roughEstimateOfTTFB: timingSummary.metrics.timeToFirstByte,
|
|
79
|
-
roughEstimateOfLCPLoadStart: timingSummary.metrics.
|
|
80
|
-
roughEstimateOfLCPLoadEnd: timingSummary.metrics.
|
|
79
|
+
roughEstimateOfLCPLoadStart: timingSummary.metrics.lcpLoadDelay,
|
|
80
|
+
roughEstimateOfLCPLoadEnd: timingSummary.metrics.lcpLoadDuration,
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
const score = Audit.computeLogNormalScore(
|
|
@@ -57,12 +57,10 @@ class CrawlableAnchors extends Audit {
|
|
|
57
57
|
href,
|
|
58
58
|
attributeNames = [],
|
|
59
59
|
listeners = [],
|
|
60
|
-
ancestorListeners = [],
|
|
61
60
|
}) => {
|
|
62
61
|
rawHref = rawHref.replace( /\s/g, '');
|
|
63
62
|
name = name.trim();
|
|
64
63
|
role = role.trim();
|
|
65
|
-
const hasListener = Boolean(listeners.length || ancestorListeners.length);
|
|
66
64
|
|
|
67
65
|
if (role.length > 0) return;
|
|
68
66
|
// Ignore mailto links even if they use one of the failing patterns. See https://github.com/GoogleChrome/lighthouse/issues/11443#issuecomment-694898412
|
|
@@ -86,7 +84,8 @@ class CrawlableAnchors extends Audit {
|
|
|
86
84
|
!attributeNames.includes('href') &&
|
|
87
85
|
hrefAssociatedAttributes.every(attribute => !attributeNames.includes(attribute))
|
|
88
86
|
) {
|
|
89
|
-
|
|
87
|
+
// If it has an even listener (e.g. onclick) then we can't assume it's a placeholder. Therefore we consider it failing.
|
|
88
|
+
return Boolean(listeners.length);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
if (href === '') return true;
|
|
@@ -9,7 +9,7 @@ import * as i18n from '../../../lib/i18n/i18n.js';
|
|
|
9
9
|
|
|
10
10
|
const UIStrings = {
|
|
11
11
|
/** Description of a Lighthouse audit that provides detail on the structured data in a page. "Structured data" is a standardized data format on a page that helps a search engine categorize and understand its contents. This description 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. */
|
|
12
|
-
description: 'Run the [Structured Data Testing Tool](https://
|
|
12
|
+
description: 'Run the [Structured Data Testing Tool](https://developers.google.com/search/docs/appearance/structured-data/) to validate structured data. [Learn more about Structured Data](https://developer.chrome.com/docs/lighthouse/seo/structured-data/).',
|
|
13
13
|
/** Title of a Lighthouse audit that prompts users to manually check their page for valid structured data. "Structured data" is a standardized data format on a page that helps a search engine categorize and understand its contents. */
|
|
14
14
|
title: 'Structured data is valid',
|
|
15
15
|
};
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
export default ServerResponseTime;
|
|
2
2
|
declare class ServerResponseTime extends Audit {
|
|
3
|
-
/**
|
|
4
|
-
* @param {LH.Artifacts.NetworkRequest} record
|
|
5
|
-
* @return {number|null}
|
|
6
|
-
*/
|
|
7
|
-
static calculateResponseTime(record: LH.Artifacts.NetworkRequest): number | null;
|
|
8
3
|
/**
|
|
9
4
|
* @param {LH.Artifacts} artifacts
|
|
10
5
|
* @param {LH.Audit.Context} context
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import {Audit} from './audit.js';
|
|
8
8
|
import * as i18n from '../lib/i18n/i18n.js';
|
|
9
|
-
import {
|
|
9
|
+
import {NavigationInsights} from '../computed/navigation-insights.js';
|
|
10
10
|
|
|
11
11
|
const UIStrings = {
|
|
12
12
|
/** Title of a diagnostic audit that provides detail on how long it took from starting a request to when the server started responding. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
|
|
@@ -21,9 +21,6 @@ const UIStrings = {
|
|
|
21
21
|
|
|
22
22
|
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
23
23
|
|
|
24
|
-
// Due to the way that DevTools throttling works we cannot see if server response took less than ~570ms.
|
|
25
|
-
// We set our failure threshold to 600ms to avoid those false positives but we want devs to shoot for 100ms.
|
|
26
|
-
const TOO_SLOW_THRESHOLD_MS = 600;
|
|
27
24
|
const TARGET_MS = 100;
|
|
28
25
|
|
|
29
26
|
class ServerResponseTime extends Audit {
|
|
@@ -38,41 +35,30 @@ class ServerResponseTime extends Audit {
|
|
|
38
35
|
description: str_(UIStrings.description),
|
|
39
36
|
supportedModes: ['navigation'],
|
|
40
37
|
guidanceLevel: 1,
|
|
41
|
-
requiredArtifacts: ['
|
|
38
|
+
requiredArtifacts: ['Trace', 'SourceMaps'],
|
|
42
39
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
43
40
|
};
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
/**
|
|
47
|
-
* @param {LH.Artifacts.NetworkRequest} record
|
|
48
|
-
* @return {number|null}
|
|
49
|
-
*/
|
|
50
|
-
static calculateResponseTime(record) {
|
|
51
|
-
// Lightrider does not have timings for sendEnd, but we do have this timing which should be
|
|
52
|
-
// close to the response time.
|
|
53
|
-
if (global.isLightrider && record.lrStatistics) return record.lrStatistics.requestMs;
|
|
54
|
-
|
|
55
|
-
if (!record.timing) return null;
|
|
56
|
-
return record.timing.receiveHeadersStart - record.timing.sendEnd;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
43
|
/**
|
|
60
44
|
* @param {LH.Artifacts} artifacts
|
|
61
45
|
* @param {LH.Audit.Context} context
|
|
62
46
|
* @return {Promise<LH.Audit.Product>}
|
|
63
47
|
*/
|
|
64
48
|
static async audit(artifacts, context) {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
49
|
+
const settings = context.settings;
|
|
50
|
+
const trace = artifacts.Trace;
|
|
51
|
+
const SourceMaps = artifacts.SourceMaps;
|
|
52
|
+
const navInsights = await NavigationInsights.request({trace, settings, SourceMaps}, context);
|
|
53
|
+
const responseTime = navInsights.model.DocumentLatency.data?.serverResponseTime;
|
|
54
|
+
const url = navInsights.model.DocumentLatency.data?.documentRequest?.args.data.url;
|
|
69
55
|
|
|
70
|
-
|
|
71
|
-
if (responseTime === null) {
|
|
56
|
+
if (responseTime === undefined || !url) {
|
|
72
57
|
throw new Error('no timing found for main resource');
|
|
73
58
|
}
|
|
74
59
|
|
|
75
|
-
const passed =
|
|
60
|
+
const passed =
|
|
61
|
+
Boolean(navInsights.model.DocumentLatency.data?.checklist.serverResponseIsFast.value);
|
|
76
62
|
const displayValue = str_(UIStrings.displayValue, {timeInMs: responseTime});
|
|
77
63
|
|
|
78
64
|
/** @type {LH.Audit.Details.Opportunity['headings']} */
|
|
@@ -84,7 +70,7 @@ class ServerResponseTime extends Audit {
|
|
|
84
70
|
const overallSavingsMs = Math.max(responseTime - TARGET_MS, 0);
|
|
85
71
|
const details = Audit.makeOpportunityDetails(
|
|
86
72
|
headings,
|
|
87
|
-
[{url
|
|
73
|
+
[{url, responseTime}],
|
|
88
74
|
{overallSavingsMs}
|
|
89
75
|
);
|
|
90
76
|
|
|
@@ -162,10 +162,10 @@ class CumulativeLayoutShift {
|
|
|
162
162
|
await processor.parse(/** @type {import('@paulirish/trace_engine').Types.Events.Event[]} */ (
|
|
163
163
|
events
|
|
164
164
|
), {});
|
|
165
|
-
if (!processor.
|
|
165
|
+
if (!processor.data) {
|
|
166
166
|
throw new Error('null trace engine result');
|
|
167
167
|
}
|
|
168
|
-
return processor.
|
|
168
|
+
return processor.data.LayoutShifts.sessionMaxScore;
|
|
169
169
|
};
|
|
170
170
|
const cumulativeLayoutShift = await run(allFrameShiftEvents.map(e => e.event));
|
|
171
171
|
const cumulativeLayoutShiftMainFrame = await run(mainFrameShiftEvents.map(e => e.event));
|
|
@@ -38,15 +38,15 @@ async function getComputationDataParamsFromTrace(data, context) {
|
|
|
38
38
|
|
|
39
39
|
const graph = await PageDependencyGraph.request({...data, fromTrace: true}, context);
|
|
40
40
|
const traceEngineResult = await TraceEngineResult.request(data, context);
|
|
41
|
-
const frameId = traceEngineResult.
|
|
41
|
+
const frameId = traceEngineResult.data.Meta.mainFrameId;
|
|
42
42
|
const navigationId =
|
|
43
|
-
traceEngineResult.
|
|
43
|
+
traceEngineResult.data.Meta.mainFrameNavigations[0].args.data?.navigationId;
|
|
44
44
|
if (!navigationId) {
|
|
45
45
|
throw new Error(`Lantern metrics could not be calculated due to missing navigation id`);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const processedNavigation = Lantern.TraceEngineComputationData.createProcessedNavigation(
|
|
49
|
-
traceEngineResult.
|
|
49
|
+
traceEngineResult.data, frameId, navigationId);
|
|
50
50
|
const simulator = data.simulator || (await LoadSimulator.request(data, context));
|
|
51
51
|
|
|
52
52
|
return {simulator, graph, processedNavigation};
|
|
@@ -2,20 +2,25 @@ export { LCPBreakdownComputed as LCPBreakdown };
|
|
|
2
2
|
declare const LCPBreakdownComputed: typeof LCPBreakdown & {
|
|
3
3
|
request: (dependencies: import("../../index.js").Artifacts.MetricComputationDataInput, context: LH.Artifacts.ComputedContext) => Promise<{
|
|
4
4
|
ttfb: number;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
loadDelay?: number;
|
|
6
|
+
loadDuration?: number;
|
|
7
|
+
renderDelay?: number;
|
|
7
8
|
}>;
|
|
8
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Note: this omits renderDelay for simulated throttling.
|
|
12
|
+
*/
|
|
9
13
|
declare class LCPBreakdown {
|
|
10
14
|
/**
|
|
11
15
|
* @param {LH.Artifacts.MetricComputationDataInput} data
|
|
12
16
|
* @param {LH.Artifacts.ComputedContext} context
|
|
13
|
-
* @return {Promise<{ttfb: number,
|
|
17
|
+
* @return {Promise<{ttfb: number, loadDelay?: number, loadDuration?: number, renderDelay?: number}>}
|
|
14
18
|
*/
|
|
15
19
|
static compute_(data: LH.Artifacts.MetricComputationDataInput, context: LH.Artifacts.ComputedContext): Promise<{
|
|
16
20
|
ttfb: number;
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
loadDelay?: number;
|
|
22
|
+
loadDuration?: number;
|
|
23
|
+
renderDelay?: number;
|
|
19
24
|
}>;
|
|
20
25
|
}
|
|
21
26
|
//# sourceMappingURL=lcp-breakdown.d.ts.map
|