lighthouse 11.7.1 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +2 -2
- package/cli/bin.js +0 -7
- package/cli/cli-flags.d.ts +1 -5
- package/cli/cli-flags.js +4 -8
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -14
- package/cli/test/smokehouse/config/exclusions.js +3 -0
- package/cli/test/smokehouse/core-tests.js +6 -20
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +2 -2
- package/core/audits/accessibility/aria-conditional-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-conditional-attr.js +43 -0
- package/core/audits/accessibility/{duplicate-id-active.d.ts → aria-deprecated-role.d.ts} +3 -3
- package/core/audits/accessibility/aria-deprecated-role.js +43 -0
- package/core/audits/accessibility/aria-prohibited-attr.d.ts +10 -0
- package/core/audits/accessibility/aria-prohibited-attr.js +44 -0
- package/core/audits/accessibility/target-size.js +0 -1
- package/core/audits/byte-efficiency/byte-efficiency-audit.d.ts +0 -16
- package/core/audits/byte-efficiency/byte-efficiency-audit.js +1 -38
- package/core/audits/byte-efficiency/offscreen-images.d.ts +0 -11
- package/core/audits/byte-efficiency/offscreen-images.js +0 -15
- package/core/audits/byte-efficiency/render-blocking-resources.js +27 -26
- package/core/audits/byte-efficiency/unminified-css.js +2 -2
- package/core/audits/byte-efficiency/unused-css-rules.js +3 -1
- package/core/audits/dobetterweb/uses-http2.d.ts +0 -13
- package/core/audits/dobetterweb/uses-http2.js +4 -38
- package/core/audits/font-display.js +2 -2
- package/core/audits/layout-shifts.js +1 -1
- package/core/audits/preload-fonts.d.ts +1 -5
- package/core/audits/preload-fonts.js +1 -10
- package/core/audits/prioritize-lcp-image.js +2 -2
- package/core/audits/redirects-http.d.ts +19 -0
- package/core/audits/redirects-http.js +75 -0
- package/core/audits/resource-summary.d.ts +2 -0
- package/core/audits/resource-summary.js +5 -4
- package/core/audits/seo/is-crawlable.d.ts +2 -1
- package/core/audits/seo/link-text.js +12 -0
- package/core/audits/uses-rel-preload.d.ts +1 -5
- package/core/audits/uses-rel-preload.js +5 -15
- package/core/audits/work-during-interaction.d.ts +2 -2
- package/core/audits/work-during-interaction.js +2 -2
- package/core/computed/js-bundles.d.ts +1 -1
- package/core/computed/metrics/lantern-first-contentful-paint.d.ts +13 -82
- package/core/computed/metrics/lantern-first-contentful-paint.js +16 -178
- package/core/computed/metrics/lantern-first-meaningful-paint.d.ts +13 -12
- package/core/computed/metrics/lantern-first-meaningful-paint.js +11 -49
- package/core/computed/metrics/lantern-interactive.d.ts +13 -21
- package/core/computed/metrics/lantern-interactive.js +12 -84
- package/core/computed/metrics/lantern-largest-contentful-paint.d.ts +13 -25
- package/core/computed/metrics/lantern-largest-contentful-paint.js +13 -80
- package/core/computed/metrics/lantern-max-potential-fid.d.ts +13 -24
- package/core/computed/metrics/lantern-max-potential-fid.js +12 -64
- package/core/computed/metrics/lantern-metric.d.ts +14 -18
- package/core/computed/metrics/lantern-metric.js +34 -30
- package/core/computed/metrics/lantern-speed-index.d.ts +13 -32
- package/core/computed/metrics/lantern-speed-index.js +13 -116
- package/core/computed/metrics/lantern-total-blocking-time.d.ts +13 -25
- package/core/computed/metrics/lantern-total-blocking-time.js +10 -94
- package/core/computed/metrics/metric.js +1 -3
- package/core/computed/module-duplication.d.ts +1 -1
- package/core/computed/navigation-insights.d.ts +36 -0
- package/core/computed/navigation-insights.js +35 -0
- package/core/computed/page-dependency-graph.js +3 -7
- package/core/computed/resource-summary.d.ts +10 -12
- package/core/computed/resource-summary.js +12 -19
- package/core/computed/trace-engine-result.d.ts +16 -3
- package/core/computed/trace-engine-result.js +19 -14
- package/core/computed/unused-css.d.ts +3 -1
- package/core/computed/unused-css.js +6 -5
- package/core/config/config-helpers.js +0 -4
- package/core/config/constants.js +0 -1
- package/core/config/default-config.js +63 -142
- package/core/config/experimental-config.js +11 -0
- package/core/config/filters.js +0 -1
- package/core/gather/driver/navigation.js +4 -1
- package/core/gather/driver/prepare.js +1 -1
- package/core/gather/driver/target-manager.js +4 -3
- package/core/gather/driver/wait-for-condition.js +2 -3
- package/core/gather/driver.d.ts +12 -0
- package/core/gather/driver.js +27 -0
- package/core/gather/gatherers/accessibility.js +4 -6
- package/core/gather/gatherers/css-usage.d.ts +0 -21
- package/core/gather/gatherers/css-usage.js +9 -119
- package/core/gather/gatherers/root-causes.d.ts +2 -2
- package/core/gather/gatherers/root-causes.js +6 -5
- package/core/gather/gatherers/stylesheets.d.ts +26 -0
- package/core/gather/gatherers/stylesheets.js +138 -0
- package/core/gather/gatherers/trace-elements.d.ts +2 -12
- package/core/gather/gatherers/trace-elements.js +2 -21
- package/core/gather/navigation-runner.js +3 -1
- package/core/gather/session.d.ts +8 -0
- package/core/gather/session.js +14 -1
- package/core/lib/emulation.js +2 -2
- package/core/lib/i18n/i18n.d.ts +0 -1
- package/core/lib/i18n/i18n.js +0 -2
- package/core/lib/lantern/cpu-node.d.ts +7 -1
- package/core/lib/lantern/cpu-node.js +12 -2
- package/core/lib/lantern/lantern-error.d.ts +8 -0
- package/core/lib/lantern/lantern-error.js +9 -0
- package/core/lib/lantern/metric.js +2 -6
- package/core/lib/lantern/metrics/first-contentful-paint.d.ts +79 -0
- package/core/lib/lantern/metrics/first-contentful-paint.js +200 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.d.ts +6 -0
- package/core/lib/lantern/metrics/first-meaningful-paint.js +64 -0
- package/core/lib/lantern/metrics/interactive.d.ts +26 -0
- package/core/lib/lantern/metrics/interactive.js +112 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.d.ts +19 -0
- package/core/lib/lantern/metrics/largest-contentful-paint.js +108 -0
- package/core/lib/lantern/metrics/max-potential-fid.d.ts +30 -0
- package/core/lib/lantern/metrics/max-potential-fid.js +92 -0
- package/core/lib/lantern/metrics/speed-index.d.ts +38 -0
- package/core/lib/lantern/metrics/speed-index.js +144 -0
- package/core/lib/lantern/metrics/total-blocking-time.d.ts +31 -0
- package/core/lib/lantern/metrics/total-blocking-time.js +128 -0
- package/core/lib/lantern/network-node.js +28 -4
- package/core/lib/lantern/page-dependency-graph.d.ts +4 -4
- package/core/lib/lantern/page-dependency-graph.js +19 -7
- package/core/lib/lantern/simulator/connection-pool.d.ts +2 -12
- package/core/lib/lantern/simulator/connection-pool.js +3 -22
- package/core/lib/lantern/simulator/network-analyzer.js +1 -12
- package/core/lib/lantern/simulator/simulator.d.ts +2 -4
- package/core/lib/lantern/simulator/simulator.js +7 -14
- package/core/lib/lantern/types/lantern.d.ts +5 -3
- package/core/lib/lantern-trace-saver.js +0 -1
- package/core/lib/lh-error.d.ts +9 -0
- package/core/lib/lh-error.js +13 -3
- package/core/lib/lighthouse-compatibility.js +53 -10
- package/core/lib/navigation-error.js +3 -0
- package/core/lib/network-request.d.ts +1 -0
- package/core/lib/network-request.js +28 -0
- package/core/runner.js +18 -25
- package/dist/report/bundle.esm.js +11 -112
- package/dist/report/flow.js +16 -117
- package/dist/report/standalone.js +12 -113
- package/flow-report/src/help-dialog.tsx +0 -1
- package/flow-report/src/i18n/i18n.d.ts +0 -4
- package/flow-report/src/i18n/ui-strings.d.ts +0 -1
- package/flow-report/src/i18n/ui-strings.js +0 -2
- package/flow-report/src/summary/category.tsx +10 -12
- package/package.json +5 -5
- package/readme.md +4 -4
- package/report/assets/styles.css +1 -60
- package/report/assets/templates.html +0 -95
- package/report/renderer/category-renderer.js +1 -1
- package/report/renderer/components.d.ts +2 -2
- package/report/renderer/components.js +2 -103
- package/report/renderer/dom.d.ts +1 -1
- package/report/renderer/dom.js +1 -1
- package/report/renderer/performance-category-renderer.d.ts +0 -7
- package/report/renderer/performance-category-renderer.js +1 -32
- package/report/renderer/report-renderer.js +3 -13
- package/report/renderer/report-ui-features.js +1 -1
- package/report/renderer/report-utils.d.ts +0 -1
- package/report/renderer/report-utils.js +13 -13
- package/shared/localization/locales/ar-XB.json +62 -329
- package/shared/localization/locales/ar.json +62 -329
- package/shared/localization/locales/bg.json +62 -329
- package/shared/localization/locales/ca.json +62 -329
- package/shared/localization/locales/cs.json +62 -329
- package/shared/localization/locales/da.json +62 -329
- package/shared/localization/locales/de.json +62 -329
- package/shared/localization/locales/el.json +62 -329
- package/shared/localization/locales/en-GB.json +62 -329
- package/shared/localization/locales/en-US.json +41 -272
- package/shared/localization/locales/en-XA.json +62 -329
- package/shared/localization/locales/en-XL.json +41 -272
- package/shared/localization/locales/es-419.json +62 -329
- package/shared/localization/locales/es.json +62 -329
- package/shared/localization/locales/fi.json +62 -329
- package/shared/localization/locales/fil.json +61 -328
- package/shared/localization/locales/fr.json +62 -329
- package/shared/localization/locales/he.json +62 -329
- package/shared/localization/locales/hi.json +62 -329
- package/shared/localization/locales/hr.json +63 -330
- package/shared/localization/locales/hu.json +62 -329
- package/shared/localization/locales/id.json +62 -329
- package/shared/localization/locales/it.json +62 -329
- package/shared/localization/locales/ja.json +62 -329
- package/shared/localization/locales/ko.json +62 -329
- package/shared/localization/locales/lt.json +62 -329
- package/shared/localization/locales/lv.json +62 -329
- package/shared/localization/locales/nl.json +62 -329
- package/shared/localization/locales/no.json +62 -329
- package/shared/localization/locales/pl.json +61 -328
- package/shared/localization/locales/pt-PT.json +62 -329
- package/shared/localization/locales/pt.json +64 -331
- package/shared/localization/locales/ro.json +62 -329
- package/shared/localization/locales/ru.json +62 -329
- package/shared/localization/locales/sk.json +62 -329
- package/shared/localization/locales/sl.json +62 -329
- package/shared/localization/locales/sr-Latn.json +62 -329
- package/shared/localization/locales/sr.json +62 -329
- package/shared/localization/locales/sv.json +62 -329
- package/shared/localization/locales/ta.json +61 -328
- package/shared/localization/locales/te.json +62 -329
- package/shared/localization/locales/th.json +62 -329
- package/shared/localization/locales/tr.json +62 -329
- package/shared/localization/locales/uk.json +62 -329
- package/shared/localization/locales/vi.json +61 -328
- package/shared/localization/locales/zh-HK.json +62 -329
- package/shared/localization/locales/zh-TW.json +61 -328
- package/shared/localization/locales/zh.json +62 -329
- package/tsconfig.json +1 -3
- package/types/artifacts.d.ts +21 -110
- package/types/audit.d.ts +0 -10
- package/types/config.d.ts +0 -1
- package/types/externs.d.ts +0 -2
- package/types/gatherer.d.ts +3 -0
- package/types/internal/smokehouse.d.ts +1 -1
- package/types/lh.d.ts +0 -2
- package/types/lhr/audit-details.d.ts +9 -4
- package/types/lhr/lhr.d.ts +0 -4
- package/types/lhr/settings.d.ts +0 -4
- package/core/audits/accessibility/duplicate-id-active.js +0 -42
- package/core/audits/content-width.d.ts +0 -17
- package/core/audits/content-width.js +0 -76
- package/core/audits/installable-manifest.d.ts +0 -111
- package/core/audits/installable-manifest.js +0 -248
- package/core/audits/layout-shift-elements.d.ts +0 -16
- package/core/audits/layout-shift-elements.js +0 -101
- package/core/audits/manual/pwa-cross-browser.d.ts +0 -12
- package/core/audits/manual/pwa-cross-browser.js +0 -40
- package/core/audits/manual/pwa-each-page-has-url.d.ts +0 -12
- package/core/audits/manual/pwa-each-page-has-url.js +0 -38
- package/core/audits/manual/pwa-page-transitions.d.ts +0 -12
- package/core/audits/manual/pwa-page-transitions.js +0 -38
- package/core/audits/maskable-icon.d.ts +0 -25
- package/core/audits/maskable-icon.js +0 -70
- package/core/audits/multi-check-audit.d.ts +0 -28
- package/core/audits/multi-check-audit.js +0 -82
- package/core/audits/no-unload-listeners.d.ts +0 -16
- package/core/audits/no-unload-listeners.js +0 -86
- package/core/audits/performance-budget.d.ts +0 -39
- package/core/audits/performance-budget.js +0 -154
- package/core/audits/script-elements-test-audit.d.ts +0 -14
- package/core/audits/script-elements-test-audit.js +0 -29
- package/core/audits/seo/plugins.d.ts +0 -15
- package/core/audits/seo/plugins.js +0 -150
- package/core/audits/seo/tap-targets.d.ts +0 -50
- package/core/audits/seo/tap-targets.js +0 -352
- package/core/audits/splash-screen.d.ts +0 -37
- package/core/audits/splash-screen.js +0 -98
- package/core/audits/themed-omnibox.d.ts +0 -42
- package/core/audits/themed-omnibox.js +0 -102
- package/core/audits/timing-budget.d.ts +0 -43
- package/core/audits/timing-budget.js +0 -175
- package/core/computed/manifest-values.d.ts +0 -24
- package/core/computed/manifest-values.js +0 -136
- package/core/config/budget.d.ts +0 -74
- package/core/config/budget.js +0 -340
- package/core/config/metrics-to-audits.d.ts +0 -19
- package/core/config/metrics-to-audits.js +0 -62
- package/core/gather/driver/service-workers.d.ts +0 -16
- package/core/gather/driver/service-workers.js +0 -52
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +0 -47
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +0 -233
- package/core/gather/gatherers/global-listeners.d.ts +0 -27
- package/core/gather/gatherers/global-listeners.js +0 -108
- package/core/gather/gatherers/installability-errors.d.ts +0 -17
- package/core/gather/gatherers/installability-errors.js +0 -56
- package/core/gather/gatherers/script-elements.d.ts +0 -21
- package/core/gather/gatherers/script-elements.js +0 -100
- package/core/gather/gatherers/seo/embedded-content.d.ts +0 -10
- package/core/gather/gatherers/seo/embedded-content.js +0 -63
- package/core/gather/gatherers/seo/tap-targets.d.ts +0 -21
- package/core/gather/gatherers/seo/tap-targets.js +0 -389
- package/core/gather/gatherers/service-worker.d.ts +0 -10
- package/core/gather/gatherers/service-worker.js +0 -32
- package/core/gather/gatherers/web-app-manifest.d.ts +0 -32
- package/core/gather/gatherers/web-app-manifest.js +0 -106
- package/report/renderer/pwa-category-renderer.d.ts +0 -55
- package/report/renderer/pwa-category-renderer.js +0 -184
- package/third-party/chromium-synchronization/installability-errors-test.js +0 -79
- package/types/lhr/budget.d.ts +0 -60
|
@@ -14,10 +14,10 @@ import * as i18n from '../../lib/i18n/i18n.js';
|
|
|
14
14
|
import {BaseNode} from '../../lib/lantern/base-node.js';
|
|
15
15
|
import {UnusedCSS} from '../../computed/unused-css.js';
|
|
16
16
|
import {NetworkRequest} from '../../lib/network-request.js';
|
|
17
|
-
import {ProcessedNavigation} from '../../computed/processed-navigation.js';
|
|
18
17
|
import {LoadSimulator} from '../../computed/load-simulator.js';
|
|
19
18
|
import {FirstContentfulPaint} from '../../computed/metrics/first-contentful-paint.js';
|
|
20
19
|
import {LCPImageRecord} from '../../computed/lcp-image-record.js';
|
|
20
|
+
import {NavigationInsights} from '../../computed/navigation-insights.js';
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
/** @typedef {import('../../lib/lantern/simulator/simulator.js').Simulator} Simulator */
|
|
@@ -44,21 +44,19 @@ const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
|
44
44
|
/**
|
|
45
45
|
* Given a simulation's nodeTimings, return an object with the nodes/timing keyed by network URL
|
|
46
46
|
* @param {LH.Gatherer.Simulation.Result['nodeTimings']} nodeTimings
|
|
47
|
-
* @return {
|
|
47
|
+
* @return {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>}
|
|
48
48
|
*/
|
|
49
|
-
function
|
|
50
|
-
/** @type {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (node.type !== 'network')
|
|
55
|
-
const nodeTiming = nodeTimings.get(node);
|
|
56
|
-
if (!nodeTiming) return;
|
|
57
|
-
|
|
58
|
-
urlMap[node.record.url] = {node, nodeTiming};
|
|
59
|
-
});
|
|
49
|
+
function getNodesAndTimingByRequestId(nodeTimings) {
|
|
50
|
+
/** @type {Map<string, {node: Node, nodeTiming: LH.Gatherer.Simulation.NodeTiming}>} */
|
|
51
|
+
const requestIdToNode = new Map();
|
|
52
|
+
|
|
53
|
+
for (const [node, nodeTiming] of nodeTimings) {
|
|
54
|
+
if (node.type !== 'network') continue;
|
|
60
55
|
|
|
61
|
-
|
|
56
|
+
requestIdToNode.set(node.record.requestId, {node, nodeTiming});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return requestIdToNode;
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
/**
|
|
@@ -119,8 +117,8 @@ class RenderBlockingResources extends Audit {
|
|
|
119
117
|
guidanceLevel: 2,
|
|
120
118
|
// TODO: look into adding an `optionalArtifacts` property that captures the non-required nature
|
|
121
119
|
// of CSSUsage
|
|
122
|
-
requiredArtifacts:
|
|
123
|
-
'GatherContext', 'Stacks'],
|
|
120
|
+
requiredArtifacts:
|
|
121
|
+
['URL', 'traces', 'devtoolsLogs', 'Stylesheets', 'CSSUsage', 'GatherContext', 'Stacks'],
|
|
124
122
|
};
|
|
125
123
|
}
|
|
126
124
|
|
|
@@ -134,9 +132,12 @@ class RenderBlockingResources extends Audit {
|
|
|
134
132
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
135
133
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
136
134
|
const simulatorData = {devtoolsLog, settings: context.settings};
|
|
137
|
-
const processedNavigation = await ProcessedNavigation.request(trace, context);
|
|
138
135
|
const simulator = await LoadSimulator.request(simulatorData, context);
|
|
139
136
|
const wastedCssBytes = await RenderBlockingResources.computeWastedCSSBytes(artifacts, context);
|
|
137
|
+
const navInsights = await NavigationInsights.request(trace, context);
|
|
138
|
+
|
|
139
|
+
const renderBlocking = navInsights.RenderBlocking;
|
|
140
|
+
if (renderBlocking instanceof Error) throw renderBlocking;
|
|
140
141
|
|
|
141
142
|
/** @type {LH.Audit.Context['settings']} */
|
|
142
143
|
const metricSettings = {
|
|
@@ -150,19 +151,18 @@ class RenderBlockingResources extends Audit {
|
|
|
150
151
|
// Cast to just `LanternMetric` since we explicitly set `throttlingMethod: 'simulate'`.
|
|
151
152
|
const fcpSimulation = /** @type {LH.Artifacts.LanternMetric} */
|
|
152
153
|
(await FirstContentfulPaint.request(metricComputationData, context));
|
|
153
|
-
const fcpTsInMs = processedNavigation.timestamps.firstContentfulPaint / 1000;
|
|
154
154
|
|
|
155
|
-
const
|
|
155
|
+
const nodesAndTimingsByRequestId =
|
|
156
|
+
getNodesAndTimingByRequestId(fcpSimulation.optimisticEstimate.nodeTimings);
|
|
156
157
|
|
|
157
158
|
const results = [];
|
|
158
159
|
const deferredNodeIds = new Set();
|
|
159
|
-
for (const resource of
|
|
160
|
-
|
|
161
|
-
if (resource.endTime > fcpTsInMs) continue;
|
|
160
|
+
for (const resource of renderBlocking.renderBlockingRequests) {
|
|
161
|
+
const nodeAndTiming = nodesAndTimingsByRequestId.get(resource.args.data.requestId);
|
|
162
162
|
// TODO: beacon to Sentry, https://github.com/GoogleChrome/lighthouse/issues/7041
|
|
163
|
-
if (!
|
|
163
|
+
if (!nodeAndTiming) continue;
|
|
164
164
|
|
|
165
|
-
const {node, nodeTiming} =
|
|
165
|
+
const {node, nodeTiming} = nodeAndTiming;
|
|
166
166
|
|
|
167
167
|
const stackSpecificTiming = computeStackSpecificTiming(node, nodeTiming, artifacts.Stacks);
|
|
168
168
|
|
|
@@ -174,8 +174,8 @@ class RenderBlockingResources extends Audit {
|
|
|
174
174
|
if (wastedMs < MINIMUM_WASTED_MS) continue;
|
|
175
175
|
|
|
176
176
|
results.push({
|
|
177
|
-
url: resource.
|
|
178
|
-
totalBytes: resource.
|
|
177
|
+
url: resource.args.data.url,
|
|
178
|
+
totalBytes: resource.args.data.encodedDataLength,
|
|
179
179
|
wastedMs,
|
|
180
180
|
});
|
|
181
181
|
}
|
|
@@ -264,6 +264,7 @@ class RenderBlockingResources extends Audit {
|
|
|
264
264
|
const wastedBytesByUrl = new Map();
|
|
265
265
|
try {
|
|
266
266
|
const unusedCssItems = await UnusedCSS.request({
|
|
267
|
+
Stylesheets: artifacts.Stylesheets,
|
|
267
268
|
CSSUsage: artifacts.CSSUsage,
|
|
268
269
|
devtoolsLog: artifacts.devtoolsLogs[Audit.DEFAULT_PASS],
|
|
269
270
|
}, context);
|
|
@@ -37,7 +37,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
|
|
|
37
37
|
description: str_(UIStrings.description),
|
|
38
38
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
39
39
|
guidanceLevel: 3,
|
|
40
|
-
requiredArtifacts: ['
|
|
40
|
+
requiredArtifacts: ['Stylesheets', 'devtoolsLogs', 'traces', 'URL', 'GatherContext'],
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -85,7 +85,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
|
|
|
85
85
|
*/
|
|
86
86
|
static audit_(artifacts, networkRecords) {
|
|
87
87
|
const items = [];
|
|
88
|
-
for (const stylesheet of artifacts.
|
|
88
|
+
for (const stylesheet of artifacts.Stylesheets) {
|
|
89
89
|
const networkRecord = networkRecords
|
|
90
90
|
.find(record => record.url === stylesheet.header.sourceURL);
|
|
91
91
|
if (!stylesheet.content) continue;
|
|
@@ -34,7 +34,8 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
|
|
|
34
34
|
description: str_(UIStrings.description),
|
|
35
35
|
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
|
|
36
36
|
guidanceLevel: 1,
|
|
37
|
-
requiredArtifacts:
|
|
37
|
+
requiredArtifacts:
|
|
38
|
+
['Stylesheets', 'CSSUsage', 'URL', 'devtoolsLogs', 'traces', 'GatherContext'],
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -46,6 +47,7 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
|
|
|
46
47
|
*/
|
|
47
48
|
static async audit_(artifacts, _, context) {
|
|
48
49
|
const unusedCssItems = await UnusedCSS.request({
|
|
50
|
+
Stylesheets: artifacts.Stylesheets,
|
|
49
51
|
CSSUsage: artifacts.CSSUsage,
|
|
50
52
|
devtoolsLog: artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS],
|
|
51
53
|
}, context);
|
|
@@ -20,19 +20,6 @@ declare class UsesHTTP2Audit extends Audit {
|
|
|
20
20
|
simulationBefore: LH.Gatherer.Simulation.Result;
|
|
21
21
|
simulationAfter: LH.Gatherer.Simulation.Result;
|
|
22
22
|
};
|
|
23
|
-
/**
|
|
24
|
-
* Computes the estimated effect all results being converted to use http/2, the max of:
|
|
25
|
-
*
|
|
26
|
-
* - end time of the last long task in the provided graph
|
|
27
|
-
* - end time of the last node in the graph
|
|
28
|
-
* @param {Array<{url: string}>} results
|
|
29
|
-
* @param {Node} graph
|
|
30
|
-
* @param {Simulator} simulator
|
|
31
|
-
* @return {number}
|
|
32
|
-
*/
|
|
33
|
-
static computeWasteWithTTIGraph(results: Array<{
|
|
34
|
-
url: string;
|
|
35
|
-
}>, graph: Node, simulator: Simulator): number;
|
|
36
23
|
/**
|
|
37
24
|
* Determines whether a network request is a "static resource" that would benefit from H2 multiplexing.
|
|
38
25
|
* XHRs, tracking pixels, etc generally don't benefit as much because they aren't requested en-masse
|
|
@@ -15,11 +15,9 @@
|
|
|
15
15
|
import {Audit} from '../audit.js';
|
|
16
16
|
import {EntityClassification} from '../../computed/entity-classification.js';
|
|
17
17
|
import UrlUtils from '../../lib/url-utils.js';
|
|
18
|
-
import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
|
|
19
18
|
import {NetworkRequest} from '../../lib/network-request.js';
|
|
20
19
|
import {NetworkRecords} from '../../computed/network-records.js';
|
|
21
20
|
import {LoadSimulator} from '../../computed/load-simulator.js';
|
|
22
|
-
import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
|
|
23
21
|
import {LanternLargestContentfulPaint} from '../../computed/metrics/lantern-largest-contentful-paint.js';
|
|
24
22
|
import {LanternFirstContentfulPaint} from '../../computed/metrics/lantern-first-contentful-paint.js';
|
|
25
23
|
import * as i18n from '../../lib/i18n/i18n.js';
|
|
@@ -80,11 +78,9 @@ class UsesHTTP2Audit extends Audit {
|
|
|
80
78
|
options = Object.assign({label: ''}, options);
|
|
81
79
|
const beforeLabel = `${this.meta.id}-${options.label}-before`;
|
|
82
80
|
const afterLabel = `${this.meta.id}-${options.label}-after`;
|
|
83
|
-
const flexibleOrdering = true;
|
|
84
81
|
|
|
85
82
|
const urlsToChange = new Set(results.map(result => result.url));
|
|
86
|
-
const simulationBefore =
|
|
87
|
-
simulator.simulate(graph, {label: beforeLabel, flexibleOrdering});
|
|
83
|
+
const simulationBefore = simulator.simulate(graph, {label: beforeLabel});
|
|
88
84
|
|
|
89
85
|
// Update all the protocols to reflect implementing our recommendations
|
|
90
86
|
/** @type {Map<string, string>} */
|
|
@@ -97,7 +93,7 @@ class UsesHTTP2Audit extends Audit {
|
|
|
97
93
|
node.request.protocol = 'h2';
|
|
98
94
|
});
|
|
99
95
|
|
|
100
|
-
const simulationAfter = simulator.simulate(graph, {label: afterLabel
|
|
96
|
+
const simulationAfter = simulator.simulate(graph, {label: afterLabel});
|
|
101
97
|
|
|
102
98
|
// Restore the original protocol after we've done our simulation
|
|
103
99
|
graph.traverse(node => {
|
|
@@ -117,32 +113,6 @@ class UsesHTTP2Audit extends Audit {
|
|
|
117
113
|
};
|
|
118
114
|
}
|
|
119
115
|
|
|
120
|
-
/**
|
|
121
|
-
* Computes the estimated effect all results being converted to use http/2, the max of:
|
|
122
|
-
*
|
|
123
|
-
* - end time of the last long task in the provided graph
|
|
124
|
-
* - end time of the last node in the graph
|
|
125
|
-
* @param {Array<{url: string}>} results
|
|
126
|
-
* @param {Node} graph
|
|
127
|
-
* @param {Simulator} simulator
|
|
128
|
-
* @return {number}
|
|
129
|
-
*/
|
|
130
|
-
static computeWasteWithTTIGraph(results, graph, simulator) {
|
|
131
|
-
const {savings: savingsOnOverallLoad, simulationBefore, simulationAfter} =
|
|
132
|
-
this.computeWasteWithGraph(results, graph, simulator, {
|
|
133
|
-
label: 'tti',
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
const savingsOnTTI =
|
|
137
|
-
LanternInteractive.getLastLongTaskEndTime(simulationBefore.nodeTimings) -
|
|
138
|
-
LanternInteractive.getLastLongTaskEndTime(simulationAfter.nodeTimings);
|
|
139
|
-
|
|
140
|
-
const savings = Math.max(savingsOnTTI, savingsOnOverallLoad);
|
|
141
|
-
|
|
142
|
-
// Round waste to nearest 10ms
|
|
143
|
-
return Math.round(Math.max(savings, 0) / 10) * 10;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
116
|
/**
|
|
147
117
|
* Determines whether a network request is a "static resource" that would benefit from H2 multiplexing.
|
|
148
118
|
* XHRs, tracking pixels, etc generally don't benefit as much because they aren't requested en-masse
|
|
@@ -235,7 +205,6 @@ class UsesHTTP2Audit extends Audit {
|
|
|
235
205
|
* @return {Promise<LH.Audit.Product>}
|
|
236
206
|
*/
|
|
237
207
|
static async audit(artifacts, context) {
|
|
238
|
-
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
239
208
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
240
209
|
const URL = artifacts.URL;
|
|
241
210
|
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
@@ -269,7 +238,6 @@ class UsesHTTP2Audit extends Audit {
|
|
|
269
238
|
devtoolsLog,
|
|
270
239
|
settings,
|
|
271
240
|
};
|
|
272
|
-
const pageGraph = await PageDependencyGraph.request({trace, devtoolsLog, URL}, context);
|
|
273
241
|
const simulator = await LoadSimulator.request(simulatorOptions, context);
|
|
274
242
|
const metricComputationInput = Audit.makeMetricComputationDataInput(artifacts, context);
|
|
275
243
|
|
|
@@ -280,8 +248,6 @@ class UsesHTTP2Audit extends Audit {
|
|
|
280
248
|
pessimisticGraph: lcpGraph,
|
|
281
249
|
} = await LanternLargestContentfulPaint.request(metricComputationInput, context);
|
|
282
250
|
|
|
283
|
-
const wastedMsTti = UsesHTTP2Audit.computeWasteWithTTIGraph(
|
|
284
|
-
resources, pageGraph, simulator);
|
|
285
251
|
const wasteFcp =
|
|
286
252
|
UsesHTTP2Audit.computeWasteWithGraph(resources,
|
|
287
253
|
fcpGraph, simulator, {label: 'fcp'});
|
|
@@ -296,11 +262,11 @@ class UsesHTTP2Audit extends Audit {
|
|
|
296
262
|
];
|
|
297
263
|
|
|
298
264
|
const details = Audit.makeOpportunityDetails(headings, resources,
|
|
299
|
-
{overallSavingsMs:
|
|
265
|
+
{overallSavingsMs: wasteLcp.savings});
|
|
300
266
|
|
|
301
267
|
return {
|
|
302
268
|
displayValue,
|
|
303
|
-
numericValue:
|
|
269
|
+
numericValue: wasteLcp.savings,
|
|
304
270
|
numericUnit: 'millisecond',
|
|
305
271
|
score: resources.length ? 0 : 1,
|
|
306
272
|
details,
|
|
@@ -50,7 +50,7 @@ class FontDisplay extends Audit {
|
|
|
50
50
|
description: str_(UIStrings.description),
|
|
51
51
|
supportedModes: ['navigation'],
|
|
52
52
|
guidanceLevel: 3,
|
|
53
|
-
requiredArtifacts: ['devtoolsLogs', '
|
|
53
|
+
requiredArtifacts: ['devtoolsLogs', 'Stylesheets', 'URL'],
|
|
54
54
|
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
@@ -67,7 +67,7 @@ class FontDisplay extends Audit {
|
|
|
67
67
|
const failingURLs = new Set();
|
|
68
68
|
|
|
69
69
|
// Go through all the stylesheets to find all @font-face declarations
|
|
70
|
-
for (const stylesheet of artifacts.
|
|
70
|
+
for (const stylesheet of artifacts.Stylesheets) {
|
|
71
71
|
// Eliminate newlines so we can more easily scan through with a regex
|
|
72
72
|
const newlinesStripped = stylesheet.content.replace(/(\r|\n)+/g, ' ');
|
|
73
73
|
// Find the @font-faces
|
|
@@ -61,7 +61,7 @@ class LayoutShifts extends Audit {
|
|
|
61
61
|
static async audit(artifacts, context) {
|
|
62
62
|
const trace = artifacts.traces[Audit.DEFAULT_PASS];
|
|
63
63
|
const traceEngineResult = await TraceEngineResult.request({trace}, context);
|
|
64
|
-
const clusters = traceEngineResult.LayoutShifts.clusters ?? [];
|
|
64
|
+
const clusters = traceEngineResult.data.LayoutShifts.clusters ?? [];
|
|
65
65
|
const {cumulativeLayoutShift: clsSavings, impactByNodeId} =
|
|
66
66
|
await CumulativeLayoutShiftComputed.request(trace, context);
|
|
67
67
|
const traceElements = artifacts.TraceElements
|
|
@@ -14,11 +14,7 @@ declare class PreloadFontsAudit extends Audit {
|
|
|
14
14
|
* @param {LH.Audit.Context} context
|
|
15
15
|
* @return {Promise<LH.Audit.Product>}
|
|
16
16
|
*/
|
|
17
|
-
static
|
|
18
|
-
/**
|
|
19
|
-
* @return {Promise<LH.Audit.Product>}
|
|
20
|
-
*/
|
|
21
|
-
static audit(): Promise<LH.Audit.Product>;
|
|
17
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
22
18
|
}
|
|
23
19
|
export namespace UIStrings {
|
|
24
20
|
const title: string;
|
|
@@ -62,7 +62,7 @@ class PreloadFontsAudit extends Audit {
|
|
|
62
62
|
* @param {LH.Audit.Context} context
|
|
63
63
|
* @return {Promise<LH.Audit.Product>}
|
|
64
64
|
*/
|
|
65
|
-
static async
|
|
65
|
+
static async audit(artifacts, context) {
|
|
66
66
|
const devtoolsLog = artifacts.devtoolsLogs[this.DEFAULT_PASS];
|
|
67
67
|
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
|
|
68
68
|
|
|
@@ -91,15 +91,6 @@ class PreloadFontsAudit extends Audit {
|
|
|
91
91
|
notApplicable: optionalFontURLs.size === 0,
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* @return {Promise<LH.Audit.Product>}
|
|
97
|
-
*/
|
|
98
|
-
static async audit() {
|
|
99
|
-
// Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
|
|
100
|
-
// is resolved.
|
|
101
|
-
return {score: 1, notApplicable: true};
|
|
102
|
-
}
|
|
103
94
|
}
|
|
104
95
|
|
|
105
96
|
export default PreloadFontsAudit;
|
|
@@ -194,8 +194,8 @@ class PrioritizeLcpImage extends Audit {
|
|
|
194
194
|
modifiedLCPNode.removeAllDependencies();
|
|
195
195
|
modifiedLCPNode.addDependency(mainDocumentNode);
|
|
196
196
|
|
|
197
|
-
const simulationBeforeChanges = simulator.simulate(graph
|
|
198
|
-
const simulationAfterChanges = simulator.simulate(modifiedGraph
|
|
197
|
+
const simulationBeforeChanges = simulator.simulate(graph);
|
|
198
|
+
const simulationAfterChanges = simulator.simulate(modifiedGraph);
|
|
199
199
|
const lcpTimingsBefore = simulationBeforeChanges.nodeTimings.get(lcpNode);
|
|
200
200
|
if (!lcpTimingsBefore) throw new Error('Impossible - node timings should never be undefined');
|
|
201
201
|
const lcpTimingsAfter = simulationAfterChanges.nodeTimings.get(modifiedLCPNode);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default RedirectsHTTP;
|
|
2
|
+
/**
|
|
3
|
+
* An audit for checking if a site starting on http redirects to https. The audit
|
|
4
|
+
* is marked not applicable if the requestedUrl is already https.
|
|
5
|
+
*/
|
|
6
|
+
declare class RedirectsHTTP extends Audit {
|
|
7
|
+
/**
|
|
8
|
+
* @param {LH.Artifacts} artifacts
|
|
9
|
+
* @return {LH.Audit.Product}
|
|
10
|
+
*/
|
|
11
|
+
static audit(artifacts: LH.Artifacts): LH.Audit.Product;
|
|
12
|
+
}
|
|
13
|
+
export namespace UIStrings {
|
|
14
|
+
const title: string;
|
|
15
|
+
const failureTitle: string;
|
|
16
|
+
const description: string;
|
|
17
|
+
}
|
|
18
|
+
import { Audit } from './audit.js';
|
|
19
|
+
//# sourceMappingURL=redirects-http.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright 2024 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {Audit} from './audit.js';
|
|
8
|
+
import * as i18n from '../lib/i18n/i18n.js';
|
|
9
|
+
import UrlUtils from '../lib/url-utils.js';
|
|
10
|
+
|
|
11
|
+
const UIStrings = {
|
|
12
|
+
/** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is redirected to HTTPS. */
|
|
13
|
+
title: 'Redirects HTTP traffic to HTTPS',
|
|
14
|
+
/** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is not redirected to HTTPS. */
|
|
15
|
+
failureTitle: 'Does not redirect HTTP traffic to HTTPS',
|
|
16
|
+
/** Description of a Lighthouse audit that tells the user why they should direct HTTP traffic to HTTPS. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */
|
|
17
|
+
description: 'Make sure that you redirect all HTTP ' +
|
|
18
|
+
'traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An audit for checking if a site starting on http redirects to https. The audit
|
|
25
|
+
* is marked not applicable if the requestedUrl is already https.
|
|
26
|
+
*/
|
|
27
|
+
class RedirectsHTTP extends Audit {
|
|
28
|
+
/**
|
|
29
|
+
* @return {LH.Audit.Meta}
|
|
30
|
+
*/
|
|
31
|
+
static get meta() {
|
|
32
|
+
return {
|
|
33
|
+
id: 'redirects-http',
|
|
34
|
+
title: str_(UIStrings.title),
|
|
35
|
+
failureTitle: str_(UIStrings.failureTitle),
|
|
36
|
+
description: str_(UIStrings.description),
|
|
37
|
+
requiredArtifacts: ['URL'],
|
|
38
|
+
supportedModes: ['navigation'],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {LH.Artifacts} artifacts
|
|
44
|
+
* @return {LH.Audit.Product}
|
|
45
|
+
*/
|
|
46
|
+
static audit(artifacts) {
|
|
47
|
+
if (!artifacts.URL.requestedUrl) {
|
|
48
|
+
throw new Error('Missing requestedUrl');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const requestedUrl = new URL(artifacts.URL.requestedUrl);
|
|
52
|
+
const finalDisplayedUrl = new URL(artifacts.URL.finalDisplayedUrl);
|
|
53
|
+
|
|
54
|
+
// Not applicable unless starting on http.
|
|
55
|
+
const startedInsecure = requestedUrl.protocol === 'http:';
|
|
56
|
+
|
|
57
|
+
// Relax requirements on localhost.
|
|
58
|
+
const isLocalhost = UrlUtils.isLikeLocalhost(finalDisplayedUrl.hostname);
|
|
59
|
+
|
|
60
|
+
if (!startedInsecure || isLocalhost) {
|
|
61
|
+
return {
|
|
62
|
+
score: null,
|
|
63
|
+
notApplicable: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const endedSecure = finalDisplayedUrl.protocol === 'https:';
|
|
68
|
+
return {
|
|
69
|
+
score: Number(endedSecure),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default RedirectsHTTP;
|
|
75
|
+
export {UIStrings};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export default ResourceSummary;
|
|
2
|
+
export type ResourceType = import('../computed/resource-summary.js').ResourceType;
|
|
3
|
+
/** @typedef {import('../computed/resource-summary.js').ResourceType} ResourceType */
|
|
2
4
|
declare class ResourceSummary extends Audit {
|
|
3
5
|
/**
|
|
4
6
|
* @param {LH.Artifacts} artifacts
|
|
@@ -10,6 +10,8 @@ import * as i18n from '../lib/i18n/i18n.js';
|
|
|
10
10
|
|
|
11
11
|
const str_ = i18n.createIcuMessageFn(import.meta.url);
|
|
12
12
|
|
|
13
|
+
/** @typedef {import('../computed/resource-summary.js').ResourceType} ResourceType */
|
|
14
|
+
|
|
13
15
|
class ResourceSummary extends Audit {
|
|
14
16
|
/**
|
|
15
17
|
* @return {LH.Audit.Meta}
|
|
@@ -32,7 +34,7 @@ class ResourceSummary extends Audit {
|
|
|
32
34
|
static async audit(artifacts, context) {
|
|
33
35
|
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
|
|
34
36
|
const summary = await ComputedResourceSummary
|
|
35
|
-
.request({devtoolsLog, URL: artifacts.URL
|
|
37
|
+
.request({devtoolsLog, URL: artifacts.URL}, context);
|
|
36
38
|
|
|
37
39
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
38
40
|
const headings = [
|
|
@@ -41,8 +43,7 @@ class ResourceSummary extends Audit {
|
|
|
41
43
|
{key: 'transferSize', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize)},
|
|
42
44
|
];
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
/** @type {Record<LH.Budget.ResourceType, LH.IcuMessage>} */
|
|
46
|
+
/** @type {Record<ResourceType, LH.IcuMessage>} */
|
|
46
47
|
const strMappings = {
|
|
47
48
|
'total': str_(i18n.UIStrings.totalResourceType),
|
|
48
49
|
'document': str_(i18n.UIStrings.documentResourceType),
|
|
@@ -55,7 +56,7 @@ class ResourceSummary extends Audit {
|
|
|
55
56
|
'third-party': str_(i18n.UIStrings.thirdPartyResourceType),
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
const types = /** @type {Array<
|
|
59
|
+
const types = /** @type {Array<ResourceType>} */ (Object.keys(summary));
|
|
59
60
|
const rows = types.map(type => {
|
|
60
61
|
return {
|
|
61
62
|
// ResourceType is included as an "id" for ease of use.
|
|
@@ -6,11 +6,12 @@ declare class IsCrawlable extends Audit {
|
|
|
6
6
|
static handleMetaElement(metaElement: LH.Artifacts.MetaElement): {
|
|
7
7
|
source: {
|
|
8
8
|
snippet: string;
|
|
9
|
+
/** @type {Array<string|undefined>} */
|
|
9
10
|
type: "node";
|
|
10
11
|
lhId?: string | undefined;
|
|
11
12
|
path?: string | undefined;
|
|
12
13
|
selector?: string | undefined;
|
|
13
|
-
boundingRect?: import("../../../types/lhr/audit-details.js").default.Rect | undefined;
|
|
14
|
+
boundingRect?: import("../../../types/lhr/audit-details.js").default.Rect | undefined; /** @type {Array<string|undefined>} */
|
|
14
15
|
nodeLabel?: string | undefined;
|
|
15
16
|
};
|
|
16
17
|
} | undefined;
|
|
@@ -84,6 +84,18 @@ const BLOCKLIST = new Set([
|
|
|
84
84
|
'மேலும் தரவுகளுக்கு',
|
|
85
85
|
'தயவுசெய்து இங்கே அழுத்தவும்',
|
|
86
86
|
'இங்கே கிளிக் செய்யவும்',
|
|
87
|
+
// Persian
|
|
88
|
+
'اطلاعات بیشتر',
|
|
89
|
+
'اطلاعات',
|
|
90
|
+
'این',
|
|
91
|
+
'اینجا بزنید',
|
|
92
|
+
'اینجا کلیک کنید',
|
|
93
|
+
'اینجا',
|
|
94
|
+
'برو',
|
|
95
|
+
'بیشتر بخوانید',
|
|
96
|
+
'بیشتر بدانید',
|
|
97
|
+
'بیشتر',
|
|
98
|
+
'شروع',
|
|
87
99
|
]);
|
|
88
100
|
|
|
89
101
|
const UIStrings = {
|
|
@@ -45,11 +45,7 @@ declare class UsesRelPreloadAudit extends Audit {
|
|
|
45
45
|
* @param {LH.Audit.Context} context
|
|
46
46
|
* @return {Promise<LH.Audit.Product>}
|
|
47
47
|
*/
|
|
48
|
-
static
|
|
49
|
-
/**
|
|
50
|
-
* @return {Promise<LH.Audit.Product>}
|
|
51
|
-
*/
|
|
52
|
-
static audit(): Promise<LH.Audit.Product>;
|
|
48
|
+
static audit(artifacts: LH.Artifacts, context: LH.Audit.Context): Promise<LH.Audit.Product>;
|
|
53
49
|
}
|
|
54
50
|
export namespace UIStrings {
|
|
55
51
|
const title: string;
|
|
@@ -143,9 +143,9 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
143
143
|
return {wastedMs: 0, results: []};
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// Preload changes the ordering of requests, simulate the original graph
|
|
146
|
+
// Preload changes the ordering of requests, simulate the original graph
|
|
147
147
|
// to have a reasonable baseline for comparison.
|
|
148
|
-
const simulationBeforeChanges = simulator.simulate(graph
|
|
148
|
+
const simulationBeforeChanges = simulator.simulate(graph);
|
|
149
149
|
const modifiedGraph = graph.cloneWithRelationships();
|
|
150
150
|
|
|
151
151
|
/** @type {Array<LH.Gatherer.Simulation.GraphNetworkNode>} */
|
|
@@ -174,8 +174,8 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
174
174
|
node.addDependency(mainDocumentNode);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
// Once we've modified the dependencies, simulate the new graph
|
|
178
|
-
const simulationAfterChanges = simulator.simulate(modifiedGraph
|
|
177
|
+
// Once we've modified the dependencies, simulate the new graph.
|
|
178
|
+
const simulationAfterChanges = simulator.simulate(modifiedGraph);
|
|
179
179
|
const originalNodesByRecord = Array.from(simulationBeforeChanges.nodeTimings.keys())
|
|
180
180
|
// @ts-expect-error we don't care if all nodes without a record collect on `undefined`
|
|
181
181
|
.reduce((map, node) => map.set(node.record, node), new Map());
|
|
@@ -209,7 +209,7 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
209
209
|
* @param {LH.Audit.Context} context
|
|
210
210
|
* @return {Promise<LH.Audit.Product>}
|
|
211
211
|
*/
|
|
212
|
-
static async
|
|
212
|
+
static async audit(artifacts, context) {
|
|
213
213
|
const trace = artifacts.traces[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
214
214
|
const devtoolsLog = artifacts.devtoolsLogs[UsesRelPreloadAudit.DEFAULT_PASS];
|
|
215
215
|
const URL = artifacts.URL;
|
|
@@ -253,16 +253,6 @@ class UsesRelPreloadAudit extends Audit {
|
|
|
253
253
|
warnings,
|
|
254
254
|
};
|
|
255
255
|
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* @return {Promise<LH.Audit.Product>}
|
|
259
|
-
*/
|
|
260
|
-
static async audit() {
|
|
261
|
-
// Preload advice is on hold until https://github.com/GoogleChrome/lighthouse/issues/11960
|
|
262
|
-
// is resolved.
|
|
263
|
-
return {score: 1, notApplicable: true,
|
|
264
|
-
details: Audit.makeOpportunityDetails([], [], {overallSavingsMs: 0})};
|
|
265
|
-
}
|
|
266
256
|
}
|
|
267
257
|
|
|
268
258
|
export default UsesRelPreloadAudit;
|
|
@@ -32,7 +32,7 @@ declare class WorkDuringInteraction extends Audit {
|
|
|
32
32
|
startTs: number;
|
|
33
33
|
endTs: number;
|
|
34
34
|
};
|
|
35
|
-
|
|
35
|
+
processingDuration: {
|
|
36
36
|
startTs: number;
|
|
37
37
|
endTs: number;
|
|
38
38
|
};
|
|
@@ -72,7 +72,7 @@ export namespace UIStrings {
|
|
|
72
72
|
const failureTitle: string;
|
|
73
73
|
const description: string;
|
|
74
74
|
const inputDelay: string;
|
|
75
|
-
const
|
|
75
|
+
const processingDuration: string;
|
|
76
76
|
const presentationDelay: string;
|
|
77
77
|
const displayValue: string;
|
|
78
78
|
const eventTarget: string;
|
|
@@ -30,7 +30,7 @@ const UIStrings = {
|
|
|
30
30
|
/** Label for a column in a data table; entries will be information on the time that the browser is delayed before responding to user input. Ideally fits within a ~40 character limit. */
|
|
31
31
|
inputDelay: 'Input delay',
|
|
32
32
|
/** Label for a column in a data table; entries will be information on the time taken by code processing user input that delays a response to the user. Ideally fits within a ~40 character limit. */
|
|
33
|
-
|
|
33
|
+
processingDuration: 'Processing duration',
|
|
34
34
|
/** Label for a column in a data table; entries will be information on the time that the browser is delayed before presenting a response to user input on screen. Ideally fits within a ~40 character limit. */
|
|
35
35
|
presentationDelay: 'Presentation delay',
|
|
36
36
|
/**
|
|
@@ -115,7 +115,7 @@ class WorkDuringInteraction extends Audit {
|
|
|
115
115
|
const endTs = startTs + interactionData.duration * 1000;
|
|
116
116
|
return {
|
|
117
117
|
inputDelay: {startTs, endTs: processingStartTs},
|
|
118
|
-
|
|
118
|
+
processingDuration: {startTs: processingStartTs, endTs: processingEndTs},
|
|
119
119
|
presentationDelay: {startTs: processingEndTs, endTs},
|
|
120
120
|
};
|
|
121
121
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JSBundlesComputed as JSBundles };
|
|
2
2
|
declare const JSBundlesComputed: typeof JSBundles & {
|
|
3
|
-
request: (dependencies: Pick<import("../index.js").Artifacts, "
|
|
3
|
+
request: (dependencies: Pick<import("../index.js").Artifacts, "SourceMaps" | "Scripts">, context: import("../../types/utility-types.js").default.ImmutableObject<{
|
|
4
4
|
computedCache: Map<string, import("../lib/arbitrary-equality-map.js").ArbitraryEqualityMap>;
|
|
5
5
|
}>) => Promise<import("../index.js").Artifacts.Bundle[]>;
|
|
6
6
|
};
|