lighthouse 9.5.0-dev.20220509 → 9.6.1
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/changelog.md +70 -0
- package/dist/report/bundle.esm.js +400 -808
- package/dist/report/flow.js +22 -27
- package/dist/report/standalone.js +18 -23
- package/flow-report/src/summary/category.tsx +1 -1
- package/jest.config.js +1 -1
- package/lighthouse-cli/.eslintrc.cjs +4 -3
- package/lighthouse-cli/bin.js +1 -0
- package/lighthouse-cli/cli-flags.js +4 -3
- package/lighthouse-cli/commands/commands.js +1 -0
- package/lighthouse-cli/commands/list-audits.js +1 -0
- package/lighthouse-cli/commands/list-locales.js +1 -0
- package/lighthouse-cli/commands/list-trace-categories.js +1 -0
- package/lighthouse-cli/index.js +1 -0
- package/lighthouse-cli/printer.js +1 -0
- package/lighthouse-cli/run.js +24 -9
- package/lighthouse-cli/sentry-prompt.js +1 -0
- package/lighthouse-cli/test/smokehouse/core-tests.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/lib.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -0
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +23 -109
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +3 -2
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +19 -28
- package/lighthouse-cli/test/smokehouse/report-assert.js +4 -3
- package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
- package/lighthouse-cli/test/smokehouse/version-check-test.js +3 -0
- package/lighthouse-cli/test/smokehouse/version-check.js +1 -0
- package/lighthouse-core/audits/accessibility/accesskeys.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-allowed-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-body.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-focus.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-input-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-children.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-parent.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-roles.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-toggle-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr-value.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/button-name.js +1 -1
- package/lighthouse-core/audits/accessibility/bypass.js +1 -1
- package/lighthouse-core/audits/accessibility/color-contrast.js +1 -1
- package/lighthouse-core/audits/accessibility/definition-list.js +1 -1
- package/lighthouse-core/audits/accessibility/dlitem.js +1 -1
- package/lighthouse-core/audits/accessibility/document-title.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-active.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-aria.js +1 -1
- package/lighthouse-core/audits/accessibility/form-field-multiple-labels.js +1 -1
- package/lighthouse-core/audits/accessibility/frame-title.js +1 -1
- package/lighthouse-core/audits/accessibility/heading-order.js +1 -1
- package/lighthouse-core/audits/accessibility/html-has-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/html-lang-valid.js +1 -1
- package/lighthouse-core/audits/accessibility/image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/input-image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/label.js +1 -1
- package/lighthouse-core/audits/accessibility/link-name.js +1 -1
- package/lighthouse-core/audits/accessibility/list.js +1 -1
- package/lighthouse-core/audits/accessibility/listitem.js +5 -5
- package/lighthouse-core/audits/accessibility/meta-refresh.js +1 -1
- package/lighthouse-core/audits/accessibility/meta-viewport.js +1 -1
- package/lighthouse-core/audits/accessibility/object-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/tabindex.js +1 -1
- package/lighthouse-core/audits/accessibility/td-headers-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/th-has-data-cells.js +1 -1
- package/lighthouse-core/audits/accessibility/valid-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/video-caption.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +12 -11
- package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +24 -22
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +3 -2
- package/lighthouse-core/audits/byte-efficiency/unminified-css.js +5 -3
- package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +11 -10
- package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -0
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +8 -11
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/lighthouse-core/audits/deprecations.js +598 -8
- package/lighthouse-core/audits/diagnostics.js +3 -4
- package/lighthouse-core/audits/dobetterweb/doctype.js +9 -20
- package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/no-document-write.js +1 -1
- package/lighthouse-core/audits/dobetterweb/notification-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -2
- package/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +1 -1
- package/lighthouse-core/audits/errors-in-console.js +2 -2
- package/lighthouse-core/audits/long-tasks.js +2 -3
- package/lighthouse-core/audits/metrics/experimental-interaction-to-next-paint.js +3 -1
- package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
- package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/interactive.js +2 -3
- package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -3
- package/lighthouse-core/audits/metrics/speed-index.js +2 -3
- package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -3
- package/lighthouse-core/audits/metrics.js +2 -3
- package/lighthouse-core/audits/no-unload-listeners.js +15 -7
- package/lighthouse-core/audits/predictive-perf.js +1 -2
- package/lighthouse-core/audits/preload-lcp-image.js +3 -3
- package/lighthouse-core/audits/redirects.js +1 -1
- package/lighthouse-core/audits/script-treemap-data.js +45 -45
- package/lighthouse-core/audits/seo/http-status-code.js +4 -2
- package/lighthouse-core/audits/seo/link-text.js +0 -2
- package/lighthouse-core/audits/server-response-time.js +17 -2
- package/lighthouse-core/audits/service-worker.js +2 -7
- package/lighthouse-core/audits/timing-budget.js +2 -3
- package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
- package/lighthouse-core/audits/uses-rel-preload.js +1 -1
- package/lighthouse-core/audits/valid-source-maps.js +14 -12
- package/lighthouse-core/audits/violation-audit.js +1 -1
- package/lighthouse-core/audits/work-during-interaction.js +280 -0
- package/lighthouse-core/computed/critical-request-chains.js +9 -5
- package/lighthouse-core/computed/js-bundles.js +11 -11
- package/lighthouse-core/computed/main-resource.js +2 -3
- package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-metric.js +5 -3
- package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/metric.js +0 -1
- package/lighthouse-core/computed/metrics/responsiveness.js +12 -9
- package/lighthouse-core/computed/metrics/speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/timing-summary.js +6 -13
- package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
- package/lighthouse-core/computed/module-duplication.js +5 -6
- package/lighthouse-core/computed/page-dependency-graph.js +28 -55
- package/lighthouse-core/computed/resource-summary.js +5 -5
- package/lighthouse-core/computed/unused-css.js +7 -6
- package/lighthouse-core/computed/unused-javascript-summary.js +36 -16
- package/lighthouse-core/config/budget.js +2 -2
- package/lighthouse-core/config/default-config.js +1 -2
- package/lighthouse-core/config/metrics-to-audits.js +5 -0
- package/lighthouse-core/fraggle-rock/api.js +1 -1
- package/lighthouse-core/fraggle-rock/config/default-config.js +8 -5
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +3 -6
- package/lighthouse-core/fraggle-rock/gather/driver.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +26 -51
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
- package/lighthouse-core/fraggle-rock/gather/session.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -5
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +6 -6
- package/lighthouse-core/gather/connections/cri.js +0 -1
- package/lighthouse-core/gather/driver/execution-context.js +2 -4
- package/lighthouse-core/gather/driver/navigation.js +9 -9
- package/lighthouse-core/gather/driver/network-monitor.js +3 -16
- package/lighthouse-core/gather/driver.js +1 -6
- package/lighthouse-core/gather/fetcher.js +210 -34
- package/lighthouse-core/gather/gather-runner.js +17 -13
- package/lighthouse-core/gather/gatherers/accessibility.js +4 -16
- package/lighthouse-core/gather/gatherers/console-messages.js +2 -4
- package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +2 -4
- package/lighthouse-core/gather/gatherers/full-page-screenshot.js +2 -3
- package/lighthouse-core/gather/gatherers/js-usage.js +87 -12
- package/lighthouse-core/gather/gatherers/link-elements.js +14 -12
- package/lighthouse-core/gather/gatherers/main-document-content.js +8 -8
- package/lighthouse-core/gather/gatherers/script-elements.js +56 -7
- package/lighthouse-core/gather/gatherers/seo/robots-txt.js +30 -2
- package/lighthouse-core/gather/gatherers/source-maps.js +1 -3
- package/lighthouse-core/gather/gatherers/trace-elements.js +21 -2
- package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
- package/lighthouse-core/index.js +2 -26
- package/lighthouse-core/lib/cdt/generated/SourceMap.js +1 -1
- package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +29 -8
- package/lighthouse-core/lib/navigation-error.js +4 -13
- package/lighthouse-core/lib/script-helpers.js +6 -11
- package/lighthouse-core/lib/url-shim.js +2 -2
- package/lighthouse-core/runner.js +5 -0
- package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -0
- package/lighthouse-core/util-commonjs.js +24 -28
- package/package.json +12 -12
- package/readme.md +1 -1
- package/report/.eslintrc.cjs +1 -3
- package/report/assets/styles.css +10 -12
- package/report/assets/templates.html +9 -10
- package/report/clients/bundle.js +1 -0
- package/report/clients/standalone.js +1 -0
- package/report/generator/report-generator.js +21 -46
- package/report/renderer/api.js +1 -0
- package/report/renderer/category-renderer.js +1 -0
- package/report/renderer/components.js +304 -303
- package/report/renderer/crc-details-renderer.js +1 -0
- package/report/renderer/details-renderer.js +10 -10
- package/report/renderer/dom.js +1 -0
- package/report/renderer/drop-down-menu.js +1 -0
- package/report/renderer/element-screenshot-renderer.js +4 -0
- package/report/renderer/features-util.js +1 -0
- package/report/renderer/i18n.js +62 -118
- package/report/renderer/logger.js +1 -0
- package/report/renderer/open-tab.js +3 -1
- package/report/renderer/performance-category-renderer.js +1 -0
- package/report/renderer/pwa-category-renderer.js +1 -0
- package/report/renderer/report-renderer.js +1 -0
- package/report/renderer/report-ui-features.js +1 -0
- package/report/renderer/snippet-renderer.js +1 -0
- package/report/renderer/swap-locale-feature.js +1 -0
- package/report/renderer/text-encoding.js +1 -0
- package/report/renderer/topbar-features.js +1 -0
- package/report/renderer/util.js +24 -27
- package/report/test/clients/bundle-test.js +4 -0
- package/report/test/generator/file-namer-test.js +1 -0
- package/report/test/generator/report-generator-test.js +20 -25
- package/report/test/renderer/category-renderer-test.js +3 -0
- package/report/test/renderer/components-test.js +3 -0
- package/report/test/renderer/crc-details-renderer-test.js +3 -0
- package/report/test/renderer/details-renderer-test.js +12 -58
- package/report/test/renderer/dom-test.js +3 -0
- package/report/test/renderer/element-screenshot-renderer-test.js +6 -3
- package/report/test/renderer/i18n-test.js +25 -70
- package/report/test/renderer/performance-category-renderer-test.js +4 -11
- package/report/test/renderer/pwa-category-renderer-test.js +3 -0
- package/report/test/renderer/report-renderer-axe-test.js +3 -0
- package/report/test/renderer/report-renderer-test.js +3 -0
- package/report/test/renderer/report-ui-features-test.js +3 -0
- package/report/test/renderer/snippet-renderer-test.js +3 -0
- package/report/test/renderer/text-encoding-test.js +3 -0
- package/report/test/renderer/util-test.js +5 -2
- package/report/test-assets/faux-psi.js +1 -2
- package/shared/localization/locales/en-US.json +260 -53
- package/shared/localization/locales/en-XL.json +260 -53
- package/shared/test/localization/format-test.js +2 -0
- package/shared/test/localization/locales-test.js +2 -0
- package/shared/test/localization/swap-locale-test.js +2 -0
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -0
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
- package/tsconfig.json +0 -1
- package/types/artifacts.d.ts +9 -48
- package/types/config.d.ts +0 -2
- package/types/externs.d.ts +2 -2
- package/types/gatherer.d.ts +2 -1
- package/types/global-lh.d.ts +0 -3
- package/types/lhr/audit-details.d.ts +3 -1
- package/types/lhr/lhr.d.ts +2 -2
- package/types/lhr/treemap.d.ts +1 -0
- package/lighthouse-core/audits/script-elements-test-audit.js +0 -30
- package/lighthouse-core/gather/gatherers/scripts.js +0 -154
- package/report/test/.eslintrc.cjs +0 -11
- package/shared/test/localization/.eslintrc.cjs +0 -11
|
@@ -146,5 +146,5 @@ class LanternSpeedIndex extends LanternMetric {
|
|
|
146
146
|
|
|
147
147
|
module.exports = makeComputedArtifact(
|
|
148
148
|
LanternSpeedIndex,
|
|
149
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
149
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
150
150
|
);
|
|
@@ -122,5 +122,5 @@ class LanternTotalBlockingTime extends LanternMetric {
|
|
|
122
122
|
|
|
123
123
|
module.exports = makeComputedArtifact(
|
|
124
124
|
LanternTotalBlockingTime,
|
|
125
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
125
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
126
126
|
);
|
|
@@ -41,5 +41,5 @@ class LargestContentfulPaintAllFrames extends NavigationMetric {
|
|
|
41
41
|
|
|
42
42
|
module.exports = makeComputedArtifact(
|
|
43
43
|
LargestContentfulPaintAllFrames,
|
|
44
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
44
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
45
45
|
);
|
|
@@ -48,5 +48,5 @@ class LargestContentfulPaint extends NavigationMetric {
|
|
|
48
48
|
|
|
49
49
|
module.exports = makeComputedArtifact(
|
|
50
50
|
LargestContentfulPaint,
|
|
51
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
51
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
52
52
|
);
|
|
@@ -41,5 +41,5 @@ class MaxPotentialFID extends NavigationMetric {
|
|
|
41
41
|
|
|
42
42
|
module.exports = makeComputedArtifact(
|
|
43
43
|
MaxPotentialFID,
|
|
44
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
44
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
45
45
|
);
|
|
@@ -25,11 +25,14 @@
|
|
|
25
25
|
* @property {number} interactionId
|
|
26
26
|
*/
|
|
27
27
|
/** @typedef {LH.Trace.AsyncEvent & {name: 'EventTiming', args: {data: EventTimingData}}} EventTimingEvent */
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* A fallback EventTiming placeholder, used if updated EventTiming events are not available.
|
|
30
|
+
* TODO: Remove once 103.0.5052.0 is sufficiently released.
|
|
31
|
+
* @typedef {{name: 'FallbackTiming', duration: number}} FallbackTimingEvent
|
|
32
|
+
*/
|
|
29
33
|
|
|
30
34
|
const makeComputedArtifact = require('../computed-artifact.js');
|
|
31
35
|
const ProcessedTrace = require('../processed-trace.js');
|
|
32
|
-
const LHError = require('../../lib/lh-error.js');
|
|
33
36
|
|
|
34
37
|
const KEYBOARD_EVENTS = new Set(['keydown', 'keypress', 'keyup']);
|
|
35
38
|
const CLICK_TAP_DRAG_EVENTS = new Set([
|
|
@@ -77,7 +80,7 @@ class Responsiveness {
|
|
|
77
80
|
* one interaction had this duration by returning the first found.
|
|
78
81
|
* @param {ResponsivenessEvent} responsivenessEvent
|
|
79
82
|
* @param {LH.Trace} trace
|
|
80
|
-
* @return {EventTimingEvent}
|
|
83
|
+
* @return {EventTimingEvent|FallbackTimingEvent}
|
|
81
84
|
*/
|
|
82
85
|
static findInteractionEvent(responsivenessEvent, {traceEvents}) {
|
|
83
86
|
const candidates = traceEvents.filter(/** @return {evt is EventTimingEvent} */ evt => {
|
|
@@ -85,12 +88,12 @@ class Responsiveness {
|
|
|
85
88
|
return evt.name === 'EventTiming' && evt.ph !== 'e';
|
|
86
89
|
});
|
|
87
90
|
|
|
88
|
-
if (candidates.length && !candidates
|
|
91
|
+
if (candidates.length && !candidates.some(candidate => candidate.args.data?.frame)) {
|
|
89
92
|
// Full EventTiming data added in https://crrev.com/c/3632661
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
return {
|
|
94
|
+
name: 'FallbackTiming',
|
|
95
|
+
duration: responsivenessEvent.args.data.maxDuration,
|
|
96
|
+
};
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
const {maxDuration, interactionType} = responsivenessEvent.args.data;
|
|
@@ -131,7 +134,7 @@ class Responsiveness {
|
|
|
131
134
|
/**
|
|
132
135
|
* @param {{trace: LH.Trace, settings: Immutable<LH.Config.Settings>}} data
|
|
133
136
|
* @param {LH.Artifacts.ComputedContext} context
|
|
134
|
-
* @return {Promise<EventTimingEvent|null>}
|
|
137
|
+
* @return {Promise<EventTimingEvent|FallbackTimingEvent|null>}
|
|
135
138
|
*/
|
|
136
139
|
static async compute_(data, context) {
|
|
137
140
|
const {settings, trace} = data;
|
|
@@ -26,12 +26,11 @@ class TimingSummary {
|
|
|
26
26
|
* @param {LH.DevtoolsLog} devtoolsLog
|
|
27
27
|
* @param {LH.Artifacts['GatherContext']} gatherContext
|
|
28
28
|
* @param {ImmutableObject<LH.Config.Settings>} settings
|
|
29
|
-
* @param {LH.Artifacts['URL']} URL
|
|
30
29
|
* @param {LH.Artifacts.ComputedContext} context
|
|
31
30
|
* @return {Promise<{metrics: LH.Artifacts.TimingSummary, debugInfo: Record<string,boolean>}>}
|
|
32
31
|
*/
|
|
33
|
-
static async summarize(trace, devtoolsLog, gatherContext, settings,
|
|
34
|
-
const metricComputationData = {trace, devtoolsLog, gatherContext, settings
|
|
32
|
+
static async summarize(trace, devtoolsLog, gatherContext, settings, context) {
|
|
33
|
+
const metricComputationData = {trace, devtoolsLog, gatherContext, settings};
|
|
35
34
|
/**
|
|
36
35
|
* @template TArtifacts
|
|
37
36
|
* @template TReturn
|
|
@@ -135,23 +134,17 @@ class TimingSummary {
|
|
|
135
134
|
return {metrics, debugInfo};
|
|
136
135
|
}
|
|
137
136
|
/**
|
|
138
|
-
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, gatherContext: LH.Artifacts['GatherContext']; settings: ImmutableObject<LH.Config.Settings
|
|
137
|
+
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, gatherContext: LH.Artifacts['GatherContext']; settings: ImmutableObject<LH.Config.Settings>}} data
|
|
139
138
|
* @param {LH.Artifacts.ComputedContext} context
|
|
140
139
|
* @return {Promise<{metrics: LH.Artifacts.TimingSummary, debugInfo: Record<string,boolean>}>}
|
|
141
140
|
*/
|
|
142
141
|
static async compute_(data, context) {
|
|
143
|
-
return TimingSummary.summarize(
|
|
144
|
-
|
|
145
|
-
data.devtoolsLog,
|
|
146
|
-
data.gatherContext,
|
|
147
|
-
data.settings,
|
|
148
|
-
data.URL,
|
|
149
|
-
context
|
|
150
|
-
);
|
|
142
|
+
return TimingSummary.summarize(data.trace, data.devtoolsLog, data.gatherContext, data.settings,
|
|
143
|
+
context);
|
|
151
144
|
}
|
|
152
145
|
}
|
|
153
146
|
|
|
154
147
|
module.exports = makeComputedArtifact(
|
|
155
148
|
TimingSummary,
|
|
156
|
-
['devtoolsLog', 'gatherContext', 'settings', 'trace'
|
|
149
|
+
['devtoolsLog', 'gatherContext', 'settings', 'trace']
|
|
157
150
|
);
|
|
@@ -70,5 +70,5 @@ class TotalBlockingTime extends ComputedMetric {
|
|
|
70
70
|
|
|
71
71
|
module.exports = makeComputedArtifact(
|
|
72
72
|
TotalBlockingTime,
|
|
73
|
-
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace'
|
|
73
|
+
['devtoolsLog', 'gatherContext', 'settings', 'simulator', 'trace']
|
|
74
74
|
);
|
|
@@ -43,7 +43,7 @@ class ModuleDuplication {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* @param {Map<string, Array<{
|
|
46
|
+
* @param {Map<string, Array<{scriptUrl: string, resourceSize: number}>>} moduleNameToSourceData
|
|
47
47
|
*/
|
|
48
48
|
static _normalizeAggregatedData(moduleNameToSourceData) {
|
|
49
49
|
for (const [key, originalSourceData] of moduleNameToSourceData.entries()) {
|
|
@@ -74,7 +74,7 @@ class ModuleDuplication {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
* @param {Pick<LH.Artifacts, '
|
|
77
|
+
* @param {Pick<LH.Artifacts, 'ScriptElements'|'SourceMaps'>} artifacts
|
|
78
78
|
* @param {LH.Artifacts.ComputedContext} context
|
|
79
79
|
*/
|
|
80
80
|
static async compute_(artifacts, context) {
|
|
@@ -109,7 +109,7 @@ class ModuleDuplication {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
/** @type {Map<string, Array<{
|
|
112
|
+
/** @type {Map<string, Array<{scriptUrl: string, resourceSize: number}>>} */
|
|
113
113
|
const moduleNameToSourceData = new Map();
|
|
114
114
|
for (const {rawMap, script} of bundles) {
|
|
115
115
|
const sourceDataArray = sourceDatasMap.get(rawMap);
|
|
@@ -122,8 +122,7 @@ class ModuleDuplication {
|
|
|
122
122
|
moduleNameToSourceData.set(sourceData.source, data);
|
|
123
123
|
}
|
|
124
124
|
data.push({
|
|
125
|
-
|
|
126
|
-
scriptUrl: script.url,
|
|
125
|
+
scriptUrl: script.src || '',
|
|
127
126
|
resourceSize: sourceData.resourceSize,
|
|
128
127
|
});
|
|
129
128
|
}
|
|
@@ -134,4 +133,4 @@ class ModuleDuplication {
|
|
|
134
133
|
}
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
module.exports = makeComputedArtifact(ModuleDuplication, ['
|
|
136
|
+
module.exports = makeComputedArtifact(ModuleDuplication, ['ScriptElements', 'SourceMaps']);
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
const makeComputedArtifact = require('./computed-artifact.js');
|
|
9
9
|
const NetworkNode = require('../lib/dependency-graph/network-node.js');
|
|
10
10
|
const CPUNode = require('../lib/dependency-graph/cpu-node.js');
|
|
11
|
+
const NetworkAnalyzer = require('../lib/dependency-graph/simulator/network-analyzer.js');
|
|
11
12
|
const TracingProcessor = require('../lib/tracehouse/trace-processor.js');
|
|
12
13
|
const NetworkRequest = require('../lib/network-request.js');
|
|
13
14
|
const ProcessedTrace = require('./processed-trace.js');
|
|
14
15
|
const NetworkRecords = require('./network-records.js');
|
|
15
|
-
const NetworkAnalyzer = require('../lib/dependency-graph/simulator/network-analyzer.js');
|
|
16
16
|
|
|
17
17
|
/** @typedef {import('../lib/dependency-graph/base-node.js').Node} Node */
|
|
18
|
-
/** @typedef {Omit<LH.Artifacts['URL'], 'initialUrl'|'finalUrl'>} URLArtifact */
|
|
19
18
|
|
|
20
19
|
// Shorter tasks have negligible impact on simulation results.
|
|
21
20
|
const SIGNIFICANT_DUR_THRESHOLD_MS = 10;
|
|
@@ -389,25 +388,34 @@ class PageDependencyGraph {
|
|
|
389
388
|
/**
|
|
390
389
|
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
391
390
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
392
|
-
* @param {URLArtifact} URL
|
|
393
391
|
* @return {Node}
|
|
394
392
|
*/
|
|
395
|
-
static createGraph(processedTrace, networkRecords
|
|
393
|
+
static createGraph(processedTrace, networkRecords) {
|
|
396
394
|
const networkNodeOutput = PageDependencyGraph.getNetworkNodeOutput(networkRecords);
|
|
397
395
|
const cpuNodes = PageDependencyGraph.getCPUNodes(processedTrace);
|
|
398
|
-
const {requestedUrl, mainDocumentUrl} = URL;
|
|
399
|
-
if (!requestedUrl) throw new Error('requestedUrl is required to get the root request');
|
|
400
|
-
if (!mainDocumentUrl) throw new Error('mainDocumentUrl is required to get the main resource');
|
|
401
|
-
|
|
402
|
-
const rootRequest = NetworkAnalyzer.findResourceForUrl(networkRecords, requestedUrl);
|
|
403
|
-
if (!rootRequest) throw new Error('rootRequest not found');
|
|
404
|
-
const rootNode = networkNodeOutput.idToNodeMap.get(rootRequest.requestId);
|
|
405
|
-
if (!rootNode) throw new Error('rootNode not found');
|
|
406
396
|
|
|
407
|
-
|
|
408
|
-
|
|
397
|
+
// The main document request is the earliest network request *of type document*.
|
|
398
|
+
// This will be different from the root request when there are server redirects.
|
|
399
|
+
const mainDocumentRequest = NetworkAnalyzer.findMainDocument(networkRecords);
|
|
409
400
|
const mainDocumentNode = networkNodeOutput.idToNodeMap.get(mainDocumentRequest.requestId);
|
|
410
|
-
if (!mainDocumentNode)
|
|
401
|
+
if (!mainDocumentNode) {
|
|
402
|
+
// mainDocumentNode should always be found.
|
|
403
|
+
throw new Error('mainDocumentNode not found.');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// The root request is the earliest request in the main document redirect chain.
|
|
407
|
+
// Will be undefined if there were no redirects.
|
|
408
|
+
const rootRequest = mainDocumentNode.record.redirects?.[0];
|
|
409
|
+
|
|
410
|
+
let rootNode;
|
|
411
|
+
if (rootRequest) {
|
|
412
|
+
// rootNode should always be found.
|
|
413
|
+
rootNode = rootRequest && networkNodeOutput.idToNodeMap.get(rootRequest.requestId);
|
|
414
|
+
if (!rootNode) throw new Error('rootNode not found');
|
|
415
|
+
} else {
|
|
416
|
+
// Use main document as root if there were no redirects.
|
|
417
|
+
rootNode = mainDocumentNode;
|
|
418
|
+
}
|
|
411
419
|
|
|
412
420
|
PageDependencyGraph.linkNetworkNodes(rootNode, networkNodeOutput);
|
|
413
421
|
PageDependencyGraph.linkCPUNodes(rootNode, networkNodeOutput, cpuNodes);
|
|
@@ -453,58 +461,23 @@ class PageDependencyGraph {
|
|
|
453
461
|
}
|
|
454
462
|
|
|
455
463
|
/**
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* @param {LH.DevtoolsLog} devtoolsLog
|
|
459
|
-
* @param {LH.Artifacts.NetworkRequest[]} networkRecords
|
|
460
|
-
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
461
|
-
* @return {URLArtifact}
|
|
462
|
-
*/
|
|
463
|
-
static getDocumentUrls(devtoolsLog, networkRecords, processedTrace) {
|
|
464
|
-
const mainFrameId = processedTrace.mainFrameIds.frameId;
|
|
465
|
-
|
|
466
|
-
/** @type {string|undefined} */
|
|
467
|
-
let requestedUrl;
|
|
468
|
-
/** @type {string|undefined} */
|
|
469
|
-
let mainDocumentUrl;
|
|
470
|
-
for (const event of devtoolsLog) {
|
|
471
|
-
if (event.method === 'Page.frameNavigated' && event.params.frame.id === mainFrameId) {
|
|
472
|
-
const {url} = event.params.frame;
|
|
473
|
-
// Only set requestedUrl on the first main frame navigation.
|
|
474
|
-
if (!requestedUrl) requestedUrl = url;
|
|
475
|
-
mainDocumentUrl = url;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
if (!requestedUrl || !mainDocumentUrl) throw new Error('No main frame navigations found');
|
|
479
|
-
|
|
480
|
-
const initialRequest = NetworkAnalyzer.findResourceForUrl(networkRecords, requestedUrl);
|
|
481
|
-
if (initialRequest?.redirects?.length) requestedUrl = initialRequest.redirects[0].url;
|
|
482
|
-
|
|
483
|
-
return {requestedUrl, mainDocumentUrl};
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, URL: LH.Artifacts['URL']}} data
|
|
464
|
+
* @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog}} data
|
|
488
465
|
* @param {LH.Artifacts.ComputedContext} context
|
|
489
466
|
* @return {Promise<Node>}
|
|
490
467
|
*/
|
|
491
468
|
static async compute_(data, context) {
|
|
492
|
-
const
|
|
469
|
+
const trace = data.trace;
|
|
470
|
+
const devtoolsLog = data.devtoolsLog;
|
|
493
471
|
const [processedTrace, networkRecords] = await Promise.all([
|
|
494
472
|
ProcessedTrace.request(trace, context),
|
|
495
473
|
NetworkRecords.request(devtoolsLog, context),
|
|
496
474
|
]);
|
|
497
475
|
|
|
498
|
-
|
|
499
|
-
// Calculates the URL artifact from the processed trace and DT log.
|
|
500
|
-
const URL = data.URL ||
|
|
501
|
-
PageDependencyGraph.getDocumentUrls(devtoolsLog, networkRecords, processedTrace);
|
|
502
|
-
|
|
503
|
-
return PageDependencyGraph.createGraph(processedTrace, networkRecords, URL);
|
|
476
|
+
return PageDependencyGraph.createGraph(processedTrace, networkRecords);
|
|
504
477
|
}
|
|
505
478
|
}
|
|
506
479
|
|
|
507
|
-
module.exports = makeComputedArtifact(PageDependencyGraph, ['devtoolsLog', 'trace'
|
|
480
|
+
module.exports = makeComputedArtifact(PageDependencyGraph, ['devtoolsLog', 'trace']);
|
|
508
481
|
|
|
509
482
|
/**
|
|
510
483
|
* @typedef {Object} NetworkNodeOutput
|
|
@@ -35,11 +35,11 @@ class ResourceSummary {
|
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
|
|
38
|
-
* @param {
|
|
38
|
+
* @param {string} mainResourceURL
|
|
39
39
|
* @param {ImmutableObject<LH.Budget[]|null>} budgets
|
|
40
40
|
* @return {Record<LH.Budget.ResourceType, ResourceEntry>}
|
|
41
41
|
*/
|
|
42
|
-
static summarize(networkRecords,
|
|
42
|
+
static summarize(networkRecords, mainResourceURL, budgets) {
|
|
43
43
|
/** @type {Record<LH.Budget.ResourceType, ResourceEntry>} */
|
|
44
44
|
const resourceSummary = {
|
|
45
45
|
'stylesheet': {count: 0, resourceSize: 0, transferSize: 0},
|
|
@@ -52,13 +52,13 @@ class ResourceSummary {
|
|
|
52
52
|
'total': {count: 0, resourceSize: 0, transferSize: 0},
|
|
53
53
|
'third-party': {count: 0, resourceSize: 0, transferSize: 0},
|
|
54
54
|
};
|
|
55
|
-
const budget = Budget.getMatchingBudget(budgets,
|
|
55
|
+
const budget = Budget.getMatchingBudget(budgets, mainResourceURL);
|
|
56
56
|
/** @type {ReadonlyArray<string>} */
|
|
57
57
|
let firstPartyHosts = [];
|
|
58
58
|
if (budget?.options?.firstPartyHostnames) {
|
|
59
59
|
firstPartyHosts = budget.options.firstPartyHostnames;
|
|
60
60
|
} else {
|
|
61
|
-
const rootDomain = Util.getRootDomain(
|
|
61
|
+
const rootDomain = Util.getRootDomain(mainResourceURL);
|
|
62
62
|
firstPartyHosts = [`*.${rootDomain}`];
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -107,7 +107,7 @@ class ResourceSummary {
|
|
|
107
107
|
*/
|
|
108
108
|
static async compute_(data, context) {
|
|
109
109
|
const networkRecords = await NetworkRecords.request(data.devtoolsLog, context);
|
|
110
|
-
return ResourceSummary.summarize(networkRecords, data.URL, data.budgets);
|
|
110
|
+
return ResourceSummary.summarize(networkRecords, data.URL.finalUrl, data.budgets);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -120,11 +120,12 @@ class UnusedCSS {
|
|
|
120
120
|
|
|
121
121
|
/**
|
|
122
122
|
* @param {StyleSheetInfo} stylesheetInfo The stylesheetInfo object.
|
|
123
|
+
* @param {string} pageUrl The URL of the page, used to identify inline styles.
|
|
123
124
|
* @return {LH.Audit.ByteEfficiencyItem}
|
|
124
125
|
*/
|
|
125
|
-
static mapSheetToResult(stylesheetInfo) {
|
|
126
|
+
static mapSheetToResult(stylesheetInfo, pageUrl) {
|
|
126
127
|
let url = stylesheetInfo.header.sourceURL;
|
|
127
|
-
if (!url ||
|
|
128
|
+
if (!url || url === pageUrl) {
|
|
128
129
|
const contentPreview = UnusedCSS.determineContentPreview(stylesheetInfo.content);
|
|
129
130
|
url = contentPreview;
|
|
130
131
|
}
|
|
@@ -134,20 +135,20 @@ class UnusedCSS {
|
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
/**
|
|
137
|
-
* @param {{CSSUsage: LH.Artifacts['CSSUsage'], devtoolsLog: LH.DevtoolsLog}} data
|
|
138
|
+
* @param {{CSSUsage: LH.Artifacts['CSSUsage'], URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog}} data
|
|
138
139
|
* @param {LH.Artifacts.ComputedContext} context
|
|
139
140
|
* @return {Promise<LH.Audit.ByteEfficiencyItem[]>}
|
|
140
141
|
*/
|
|
141
142
|
static async compute_(data, context) {
|
|
142
|
-
const {CSSUsage, devtoolsLog} = data;
|
|
143
|
+
const {CSSUsage, URL, devtoolsLog} = data;
|
|
143
144
|
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
144
145
|
const indexedSheets = UnusedCSS.indexStylesheetsById(CSSUsage.stylesheets, networkRecords);
|
|
145
146
|
UnusedCSS.indexUsedRules(CSSUsage.rules, indexedSheets);
|
|
146
147
|
|
|
147
148
|
const items = Object.keys(indexedSheets)
|
|
148
|
-
.map(sheetId => UnusedCSS.mapSheetToResult(indexedSheets[sheetId]));
|
|
149
|
+
.map(sheetId => UnusedCSS.mapSheetToResult(indexedSheets[sheetId], URL.finalUrl));
|
|
149
150
|
return items;
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
module.exports = makeComputedArtifact(UnusedCSS, ['CSSUsage', 'devtoolsLog']);
|
|
154
|
+
module.exports = makeComputedArtifact(UnusedCSS, ['CSSUsage', 'URL', 'devtoolsLog']);
|
|
@@ -16,14 +16,14 @@ const makeComputedArtifact = require('./computed-artifact.js');
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @typedef ComputeInput
|
|
19
|
-
* @property {string}
|
|
20
|
-
* @property {Omit<LH.Crdp.Profiler.ScriptCoverage, 'url'
|
|
19
|
+
* @property {string} url
|
|
20
|
+
* @property {Array<Omit<LH.Crdp.Profiler.ScriptCoverage, 'url'>>} scriptCoverages
|
|
21
21
|
* @property {LH.Artifacts.Bundle=} bundle
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* @typedef Summary
|
|
26
|
-
* @property {string}
|
|
26
|
+
* @property {string} url
|
|
27
27
|
* @property {number} wastedBytes
|
|
28
28
|
* @property {number} totalBytes
|
|
29
29
|
* @property {number} wastedBytes
|
|
@@ -68,24 +68,43 @@ class UnusedJavascriptSummary {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
* @param {string}
|
|
72
|
-
* @param {
|
|
71
|
+
* @param {string} url
|
|
72
|
+
* @param {ReturnType<typeof UnusedJavascriptSummary.determineLengths>} lengths
|
|
73
73
|
* @return {Summary}
|
|
74
74
|
*/
|
|
75
|
-
static createItem(
|
|
76
|
-
const wastedRatio = (
|
|
77
|
-
const wastedBytes = Math.round(
|
|
75
|
+
static createItem(url, lengths) {
|
|
76
|
+
const wastedRatio = (lengths.unused / lengths.content) || 0;
|
|
77
|
+
const wastedBytes = Math.round(lengths.content * wastedRatio);
|
|
78
78
|
|
|
79
79
|
return {
|
|
80
|
-
|
|
81
|
-
totalBytes:
|
|
80
|
+
url,
|
|
81
|
+
totalBytes: lengths.content,
|
|
82
82
|
wastedBytes,
|
|
83
83
|
wastedPercent: 100 * wastedRatio,
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* @param {WasteData} wasteData
|
|
88
|
+
* @param {WasteData[]} wasteData
|
|
89
|
+
*/
|
|
90
|
+
static determineLengths(wasteData) {
|
|
91
|
+
let unused = 0;
|
|
92
|
+
let content = 0;
|
|
93
|
+
// TODO: this is right for multiple script tags in an HTML document,
|
|
94
|
+
// but may be wrong for multiple frames using the same script resource.
|
|
95
|
+
for (const usage of wasteData) {
|
|
96
|
+
unused += usage.unusedLength;
|
|
97
|
+
content += usage.contentLength;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
content,
|
|
102
|
+
unused,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {WasteData[]} wasteData
|
|
89
108
|
* @param {LH.Artifacts.Bundle} bundle
|
|
90
109
|
*/
|
|
91
110
|
static createSourceWastedBytes(wasteData, bundle) {
|
|
@@ -112,7 +131,7 @@ class UnusedJavascriptSummary {
|
|
|
112
131
|
mapping.lastColumnNumber - 1 :
|
|
113
132
|
lineLengths[mapping.lineNumber];
|
|
114
133
|
for (let i = mapping.columnNumber; i <= lastColumnOfMapping; i++) {
|
|
115
|
-
if (wasteData.unusedByIndex[offset] === 1) {
|
|
134
|
+
if (wasteData.every(data => data.unusedByIndex[offset] === 1)) {
|
|
116
135
|
const key = mapping.sourceURL || '(unmapped)';
|
|
117
136
|
files[key] = (files[key] || 0) + 1;
|
|
118
137
|
}
|
|
@@ -136,10 +155,11 @@ class UnusedJavascriptSummary {
|
|
|
136
155
|
* @return {Promise<Summary>}
|
|
137
156
|
*/
|
|
138
157
|
static async compute_(data) {
|
|
139
|
-
const {
|
|
158
|
+
const {url, scriptCoverages, bundle} = data;
|
|
140
159
|
|
|
141
|
-
const wasteData = UnusedJavascriptSummary.computeWaste
|
|
142
|
-
const
|
|
160
|
+
const wasteData = scriptCoverages.map(UnusedJavascriptSummary.computeWaste);
|
|
161
|
+
const lengths = UnusedJavascriptSummary.determineLengths(wasteData);
|
|
162
|
+
const item = UnusedJavascriptSummary.createItem(url, lengths);
|
|
143
163
|
if (!bundle) return item;
|
|
144
164
|
|
|
145
165
|
return {
|
|
@@ -151,5 +171,5 @@ class UnusedJavascriptSummary {
|
|
|
151
171
|
|
|
152
172
|
module.exports = makeComputedArtifact(
|
|
153
173
|
UnusedJavascriptSummary,
|
|
154
|
-
['bundle', '
|
|
174
|
+
['bundle', 'scriptCoverages', 'url']
|
|
155
175
|
);
|
|
@@ -137,11 +137,11 @@ class Budget {
|
|
|
137
137
|
* If multiple budgets match based on thier 'path' property,
|
|
138
138
|
* then the last-listed of those budgets is returned.
|
|
139
139
|
* @param {Immutable<Array<LH.Budget>>|null} budgets
|
|
140
|
-
* @param {string
|
|
140
|
+
* @param {string} url
|
|
141
141
|
* @return {Immutable<LH.Budget> | undefined} budget
|
|
142
142
|
*/
|
|
143
143
|
static getMatchingBudget(budgets, url) {
|
|
144
|
-
if (budgets === null
|
|
144
|
+
if (budgets === null) return;
|
|
145
145
|
|
|
146
146
|
// Applies the LAST matching budget.
|
|
147
147
|
for (let i = budgets.length - 1; i >= 0; i--) {
|
|
@@ -41,7 +41,7 @@ const UIStrings = {
|
|
|
41
41
|
/** Description of the Accessibility category. This is displayed at the top of a list of audits focused on making web content accessible to all users. No character length limits. 'improve the accessibility of your web app' becomes link text to additional documentation. */
|
|
42
42
|
a11yCategoryDescription: 'These checks highlight opportunities to [improve the accessibility of your web app](https://web.dev/lighthouse-accessibility/). Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.',
|
|
43
43
|
/** Description of the Accessibility manual checks category. This description is displayed above a list of accessibility audits that currently have no automated test and so must be verified manually by the user. No character length limits. 'conducting an accessibility review' becomes link text to additional documentation. */
|
|
44
|
-
a11yCategoryManualDescription: 'These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://
|
|
44
|
+
a11yCategoryManualDescription: 'These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://developers.google.com/web/fundamentals/accessibility/how-to-review).',
|
|
45
45
|
/** Title of the best practices section of the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */
|
|
46
46
|
a11yBestPracticesGroupTitle: 'Best practices',
|
|
47
47
|
/** Description of the best practices section within the Accessibility category. Within this section are audits with descriptive titles that highlight common accessibility best practices. */
|
|
@@ -143,7 +143,6 @@ const defaultConfig = {
|
|
|
143
143
|
'link-elements',
|
|
144
144
|
'meta-elements',
|
|
145
145
|
'script-elements',
|
|
146
|
-
'scripts',
|
|
147
146
|
'iframe-elements',
|
|
148
147
|
'inputs',
|
|
149
148
|
'main-document-content',
|
|
@@ -48,9 +48,14 @@ const clsRelevantAudits = [
|
|
|
48
48
|
// 'preload-fonts', // actually in BP, rather than perf
|
|
49
49
|
];
|
|
50
50
|
|
|
51
|
+
const inpRelevantAudits = [
|
|
52
|
+
'work-during-interaction',
|
|
53
|
+
];
|
|
54
|
+
|
|
51
55
|
module.exports = {
|
|
52
56
|
fcpRelevantAudits,
|
|
53
57
|
lcpRelevantAudits,
|
|
54
58
|
tbtRelevantAudits,
|
|
55
59
|
clsRelevantAudits,
|
|
60
|
+
inpRelevantAudits,
|
|
56
61
|
};
|
|
@@ -13,7 +13,7 @@ const {generateFlowReportHtml} = require('../../report/generator/report-generato
|
|
|
13
13
|
const Runner = require('../runner.js');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* @param {
|
|
16
|
+
* @param {import('puppeteer').Page} page
|
|
17
17
|
* @param {ConstructorParameters<LH.UserFlow>[1]} [options]
|
|
18
18
|
*/
|
|
19
19
|
async function startFlow(page, options) {
|
|
@@ -6,19 +6,23 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const legacyDefaultConfig = require('../../config/default-config.js');
|
|
9
|
+
const m2a = require('../../config/metrics-to-audits.js');
|
|
9
10
|
const {deepClone} = require('../../config/config-helpers.js');
|
|
10
11
|
|
|
11
12
|
/** @type {LH.Config.AuditJson[]} */
|
|
12
13
|
const frAudits = [
|
|
13
14
|
'byte-efficiency/uses-responsive-images-snapshot',
|
|
14
15
|
'metrics/experimental-interaction-to-next-paint',
|
|
16
|
+
'work-during-interaction',
|
|
15
17
|
];
|
|
16
18
|
|
|
17
19
|
/** @type {Record<string, LH.Config.AuditRefJson[]>} */
|
|
18
20
|
const frCategoryAuditRefExtensions = {
|
|
19
21
|
'performance': [
|
|
20
22
|
{id: 'uses-responsive-images-snapshot', weight: 0},
|
|
21
|
-
{id: 'experimental-interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP'
|
|
23
|
+
{id: 'experimental-interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP',
|
|
24
|
+
relevantAudits: m2a.inpRelevantAudits},
|
|
25
|
+
{id: 'work-during-interaction', weight: 0},
|
|
22
26
|
],
|
|
23
27
|
};
|
|
24
28
|
|
|
@@ -66,7 +70,6 @@ const artifacts = {
|
|
|
66
70
|
RobotsTxt: '',
|
|
67
71
|
ServiceWorker: '',
|
|
68
72
|
ScriptElements: '',
|
|
69
|
-
Scripts: '',
|
|
70
73
|
SourceMaps: '',
|
|
71
74
|
Stacks: '',
|
|
72
75
|
TagsBlockingFirstPaint: '',
|
|
@@ -100,7 +103,6 @@ const defaultConfig = {
|
|
|
100
103
|
{id: artifacts.EmbeddedContent, gatherer: 'seo/embedded-content'},
|
|
101
104
|
{id: artifacts.FontSize, gatherer: 'seo/font-size'},
|
|
102
105
|
{id: artifacts.Inputs, gatherer: 'inputs'},
|
|
103
|
-
{id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
|
|
104
106
|
{id: artifacts.GlobalListeners, gatherer: 'global-listeners'},
|
|
105
107
|
{id: artifacts.IFrameElements, gatherer: 'iframe-elements'},
|
|
106
108
|
{id: artifacts.ImageElements, gatherer: 'image-elements'},
|
|
@@ -117,7 +119,6 @@ const defaultConfig = {
|
|
|
117
119
|
{id: artifacts.RobotsTxt, gatherer: 'seo/robots-txt'},
|
|
118
120
|
{id: artifacts.ServiceWorker, gatherer: 'service-worker'},
|
|
119
121
|
{id: artifacts.ScriptElements, gatherer: 'script-elements'},
|
|
120
|
-
{id: artifacts.Scripts, gatherer: 'scripts'},
|
|
121
122
|
{id: artifacts.SourceMaps, gatherer: 'source-maps'},
|
|
122
123
|
{id: artifacts.Stacks, gatherer: 'stacks'},
|
|
123
124
|
{id: artifacts.TagsBlockingFirstPaint, gatherer: 'dobetterweb/tags-blocking-first-paint'},
|
|
@@ -130,6 +131,9 @@ const defaultConfig = {
|
|
|
130
131
|
// Artifact copies are renamed for compatibility with legacy artifacts.
|
|
131
132
|
{id: artifacts.devtoolsLogs, gatherer: 'devtools-log-compat'},
|
|
132
133
|
{id: artifacts.traces, gatherer: 'trace-compat'},
|
|
134
|
+
|
|
135
|
+
// FullPageScreenshot comes at the very end so all other node analysis is captured.
|
|
136
|
+
{id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
|
|
133
137
|
],
|
|
134
138
|
navigations: [
|
|
135
139
|
{
|
|
@@ -169,7 +173,6 @@ const defaultConfig = {
|
|
|
169
173
|
artifacts.RobotsTxt,
|
|
170
174
|
artifacts.ServiceWorker,
|
|
171
175
|
artifacts.ScriptElements,
|
|
172
|
-
artifacts.Scripts,
|
|
173
176
|
artifacts.SourceMaps,
|
|
174
177
|
artifacts.Stacks,
|
|
175
178
|
artifacts.TagsBlockingFirstPaint,
|