lighthouse 9.5.0-dev.20220906 → 9.5.0-dev.20220908

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.
Files changed (150) hide show
  1. package/cli/cli-flags.js +17 -0
  2. package/cli/run.js +2 -2
  3. package/cli/test/smokehouse/core-tests.js +2 -3
  4. package/cli/test/smokehouse/report-assert.js +0 -4
  5. package/cli/test/smokehouse/smokehouse.js +6 -0
  6. package/core/audits/bootup-time.js +2 -2
  7. package/core/audits/byte-efficiency/byte-efficiency-audit.js +7 -6
  8. package/core/audits/byte-efficiency/duplicated-javascript.js +1 -1
  9. package/core/audits/byte-efficiency/legacy-javascript.js +2 -2
  10. package/core/audits/byte-efficiency/modern-image-formats.js +5 -5
  11. package/core/audits/byte-efficiency/offscreen-images.js +4 -4
  12. package/core/audits/byte-efficiency/render-blocking-resources.js +5 -5
  13. package/core/audits/byte-efficiency/total-byte-weight.js +1 -1
  14. package/core/audits/byte-efficiency/unminified-css.js +1 -1
  15. package/core/audits/byte-efficiency/unused-css-rules.js +1 -1
  16. package/core/audits/byte-efficiency/unused-javascript.js +4 -4
  17. package/core/audits/byte-efficiency/uses-long-cache-ttl.js +3 -3
  18. package/core/audits/byte-efficiency/uses-optimized-images.js +5 -5
  19. package/core/audits/byte-efficiency/uses-responsive-images-snapshot.js +2 -2
  20. package/core/audits/byte-efficiency/uses-responsive-images.js +3 -3
  21. package/core/audits/byte-efficiency/uses-text-compression.js +2 -2
  22. package/core/audits/critical-request-chains.js +1 -1
  23. package/core/audits/csp-xss.js +1 -1
  24. package/core/audits/deprecations.js +2 -2
  25. package/core/audits/diagnostics.js +7 -7
  26. package/core/audits/dobetterweb/charset.js +1 -1
  27. package/core/audits/dobetterweb/uses-http2.js +8 -8
  28. package/core/audits/errors-in-console.js +2 -2
  29. package/core/audits/final-screenshot.js +2 -2
  30. package/core/audits/font-display.js +7 -6
  31. package/core/audits/image-aspect-ratio.js +3 -3
  32. package/core/audits/image-size-responsive.js +3 -3
  33. package/core/audits/installable-manifest.js +1 -1
  34. package/core/audits/is-on-https.js +3 -3
  35. package/core/audits/long-tasks.js +4 -4
  36. package/core/audits/main-thread-tasks.js +1 -1
  37. package/core/audits/mainthread-work-breakdown.js +1 -1
  38. package/core/audits/maskable-icon.js +1 -1
  39. package/core/audits/metrics/cumulative-layout-shift.js +1 -1
  40. package/core/audits/metrics/experimental-interaction-to-next-paint.js +1 -1
  41. package/core/audits/metrics/first-contentful-paint-3g.js +1 -1
  42. package/core/audits/metrics/first-contentful-paint.js +1 -1
  43. package/core/audits/metrics/first-meaningful-paint.js +1 -1
  44. package/core/audits/metrics/interactive.js +1 -1
  45. package/core/audits/metrics/largest-contentful-paint.js +1 -1
  46. package/core/audits/metrics/max-potential-fid.js +1 -1
  47. package/core/audits/metrics/speed-index.js +1 -1
  48. package/core/audits/metrics/total-blocking-time.js +1 -1
  49. package/core/audits/metrics.js +2 -2
  50. package/core/audits/network-requests.js +4 -4
  51. package/core/audits/network-rtt.js +3 -3
  52. package/core/audits/network-server-latency.js +3 -3
  53. package/core/audits/no-unload-listeners.js +2 -2
  54. package/core/audits/performance-budget.js +2 -2
  55. package/core/audits/predictive-perf.js +8 -8
  56. package/core/audits/preload-fonts.js +1 -1
  57. package/core/audits/preload-lcp-image.js +4 -4
  58. package/core/audits/redirects.js +4 -4
  59. package/core/audits/resource-summary.js +1 -1
  60. package/core/audits/screenshot-thumbnails.js +1 -1
  61. package/core/audits/script-treemap-data.js +5 -5
  62. package/core/audits/seo/canonical.js +3 -3
  63. package/core/audits/seo/font-size.js +2 -2
  64. package/core/audits/seo/http-status-code.js +1 -1
  65. package/core/audits/seo/is-crawlable.js +1 -2
  66. package/core/audits/seo/link-text.js +2 -2
  67. package/core/audits/seo/plugins.js +0 -1
  68. package/core/audits/seo/robots-txt.js +0 -1
  69. package/core/audits/seo/tap-targets.js +2 -2
  70. package/core/audits/server-response-time.js +1 -1
  71. package/core/audits/service-worker.js +0 -1
  72. package/core/audits/splash-screen.js +1 -1
  73. package/core/audits/themed-omnibox.js +1 -1
  74. package/core/audits/third-party-facades.js +3 -3
  75. package/core/audits/third-party-summary.js +2 -2
  76. package/core/audits/timing-budget.js +2 -2
  77. package/core/audits/unsized-images.js +4 -4
  78. package/core/audits/user-timings.js +1 -1
  79. package/core/audits/uses-rel-preconnect.js +12 -10
  80. package/core/audits/uses-rel-preload.js +6 -6
  81. package/core/audits/viewport.js +2 -2
  82. package/core/audits/violation-audit.js +2 -2
  83. package/core/audits/work-during-interaction.js +4 -4
  84. package/core/computed/critical-request-chains.js +5 -3
  85. package/core/computed/image-records.js +5 -3
  86. package/core/computed/js-bundles.js +2 -1
  87. package/core/computed/load-simulator.js +3 -5
  88. package/core/computed/main-resource.js +3 -2
  89. package/core/computed/main-thread-tasks.js +3 -2
  90. package/core/computed/manifest-values.js +3 -1
  91. package/core/computed/metrics/cumulative-layout-shift.js +3 -2
  92. package/core/computed/metrics/first-contentful-paint-all-frames.js +3 -2
  93. package/core/computed/metrics/first-contentful-paint.js +4 -3
  94. package/core/computed/metrics/first-meaningful-paint.js +4 -3
  95. package/core/computed/metrics/interactive.js +4 -3
  96. package/core/computed/metrics/lantern-first-contentful-paint.js +3 -2
  97. package/core/computed/metrics/lantern-first-meaningful-paint.js +4 -3
  98. package/core/computed/metrics/lantern-interactive.js +4 -3
  99. package/core/computed/metrics/lantern-largest-contentful-paint.js +4 -3
  100. package/core/computed/metrics/lantern-max-potential-fid.js +5 -4
  101. package/core/computed/metrics/lantern-metric.js +6 -6
  102. package/core/computed/metrics/lantern-speed-index.js +5 -4
  103. package/core/computed/metrics/lantern-total-blocking-time.js +5 -4
  104. package/core/computed/metrics/largest-contentful-paint-all-frames.js +3 -2
  105. package/core/computed/metrics/largest-contentful-paint.js +4 -3
  106. package/core/computed/metrics/max-potential-fid.js +4 -3
  107. package/core/computed/metrics/metric.js +3 -3
  108. package/core/computed/metrics/navigation-metric.js +4 -3
  109. package/core/computed/metrics/responsiveness.js +3 -2
  110. package/core/computed/metrics/speed-index.js +5 -4
  111. package/core/computed/metrics/timing-summary.js +15 -14
  112. package/core/computed/metrics/total-blocking-time.js +5 -4
  113. package/core/computed/module-duplication.js +5 -3
  114. package/core/computed/network-analysis.js +3 -2
  115. package/core/computed/network-records.js +2 -1
  116. package/core/computed/page-dependency-graph.js +13 -11
  117. package/core/computed/processed-navigation.js +2 -1
  118. package/core/computed/processed-trace.js +2 -1
  119. package/core/computed/resource-summary.js +4 -3
  120. package/core/computed/screenshots.js +2 -1
  121. package/core/computed/speedline.js +3 -2
  122. package/core/computed/unused-css.js +3 -2
  123. package/core/computed/unused-javascript-summary.js +2 -1
  124. package/core/computed/user-timings.js +3 -2
  125. package/core/computed/viewport-meta.js +2 -1
  126. package/core/fraggle-rock/gather/navigation-runner.js +3 -3
  127. package/core/gather/driver/navigation.js +3 -3
  128. package/core/gather/driver/network-monitor.js +2 -2
  129. package/core/gather/gather-runner.js +3 -3
  130. package/core/gather/gatherers/dobetterweb/optimized-images.js +3 -3
  131. package/core/gather/gatherers/dobetterweb/response-compression.js +3 -3
  132. package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +1 -1
  133. package/core/gather/gatherers/inspector-issues.js +1 -1
  134. package/core/gather/gatherers/link-elements.js +1 -2
  135. package/core/gather/gatherers/main-document-content.js +1 -1
  136. package/core/gather/gatherers/script-elements.js +1 -1
  137. package/core/gather/gatherers/source-maps.js +0 -1
  138. package/core/gather/gatherers/trace-elements.js +4 -4
  139. package/core/index.js +3 -3
  140. package/core/lib/asset-saver.js +4 -4
  141. package/core/lib/dependency-graph/simulator/network-analyzer.js +2 -2
  142. package/core/lib/icons.js +0 -2
  143. package/core/lib/manifest-parser.js +0 -2
  144. package/core/lib/network-request.js +7 -7
  145. package/core/lib/{url-shim.js → url-utils.js} +4 -12
  146. package/package.json +2 -3
  147. package/report/test/renderer/performance-category-renderer-test.js +0 -1
  148. package/report/test/renderer/report-renderer-test.js +0 -1
  149. package/tsconfig.json +1 -1
  150. package/core/fraggle-rock/replay/stringify-extension.js +0 -104
package/cli/cli-flags.js CHANGED
@@ -7,6 +7,7 @@
7
7
  /* eslint-disable max-len */
8
8
 
9
9
  import fs from 'fs';
10
+ import path from 'path';
10
11
 
11
12
  import yargs from 'yargs';
12
13
  import * as yargsHelpers from 'yargs/helpers';
@@ -227,6 +228,7 @@ function getYargsParser(manualArgv) {
227
228
  },
228
229
  'output-path': {
229
230
  type: 'string',
231
+ coerce: coerceOutputPath,
230
232
  describe: `The file path to output the results. Use 'stdout' to write to stdout.
231
233
  If using JSON output, default is stdout.
232
234
  If using HTML or CSV output, default is a file in the working directory with a name based on the test URL and date.
@@ -408,6 +410,21 @@ function coerceOutput(values) {
408
410
  return validValues;
409
411
  }
410
412
 
413
+ /**
414
+ * Verifies outputPath is something we can actually write to.
415
+ * @param {unknown=} value
416
+ * @return {string=}
417
+ */
418
+ function coerceOutputPath(value) {
419
+ if (value === undefined) return;
420
+
421
+ if (typeof value !== 'string' || !value || !fs.existsSync(path.dirname(value))) {
422
+ throw new Error(`--output-path (${value}) cannot be written to`);
423
+ }
424
+
425
+ return value;
426
+ }
427
+
411
428
  /**
412
429
  * Verifies value is a string, then coerces type to LH.Locale for convenience. However, don't
413
430
  * allowlist specific locales. Why? So we can support the user who requests 'es-MX' (unsupported)
package/cli/run.js CHANGED
@@ -19,7 +19,7 @@ import * as Printer from './printer.js';
19
19
  import lighthouse, {legacyNavigation} from '../core/index.js';
20
20
  import {getLhrFilenamePrefix} from '../report/generator/file-namer.js';
21
21
  import * as assetSaver from '../core/lib/asset-saver.js';
22
- import URL from '../core/lib/url-shim.js';
22
+ import UrlUtils from '../core/lib/url-utils.js';
23
23
 
24
24
  /** @typedef {Error & {code: string, friendlyMessage?: string}} ExitError */
25
25
 
@@ -232,7 +232,7 @@ async function runLighthouse(url, flags, config) {
232
232
  }
233
233
 
234
234
  const shouldGather = flags.gatherMode || flags.gatherMode === flags.auditMode;
235
- const shouldUseLocalChrome = URL.isLikeLocalhost(flags.hostname);
235
+ const shouldUseLocalChrome = UrlUtils.isLikeLocalhost(flags.hostname);
236
236
  if (shouldGather && shouldUseLocalChrome) {
237
237
  launchedChrome = await getDebuggableChrome(flags);
238
238
  flags.port = launchedChrome.port;
@@ -42,7 +42,7 @@ import perfFonts from './test-definitions/perf-fonts.js';
42
42
  import perfFrameMetrics from './test-definitions/perf-frame-metrics.js';
43
43
  import perfPreload from './test-definitions/perf-preload.js';
44
44
  import perfTraceElements from './test-definitions/perf-trace-elements.js';
45
- // import pubads from './test-definitions/pubads.js';
45
+ import pubads from './test-definitions/pubads.js';
46
46
  import pwaAirhorner from './test-definitions/pwa-airhorner.js';
47
47
  import pwaCaltrain from './test-definitions/pwa-caltrain.js';
48
48
  import pwaChromestatus from './test-definitions/pwa-chromestatus.js';
@@ -103,8 +103,7 @@ const smokeTests = [
103
103
  perfFrameMetrics,
104
104
  perfPreload,
105
105
  perfTraceElements,
106
- // TODO(esmodules): enable when pubads is bundled again
107
- // pubads,
106
+ pubads,
108
107
  pwaAirhorner,
109
108
  pwaChromestatus,
110
109
  pwaSvgomg,
@@ -259,10 +259,6 @@ function pruneExpectations(localConsole, lhr, expected, reportOptions) {
259
259
  * @param {*} obj
260
260
  */
261
261
  function failsChromeVersionCheck(obj) {
262
- // LHR never actually run, so we can't know. Better to not prune
263
- // things than to fail loudly when accessing lhr.environment.
264
- if (!lhr.environment) return false;
265
-
266
262
  return !chromiumVersionCheck({
267
263
  version: getChromeVersionString(),
268
264
  min: obj._minChromiumVersion,
@@ -195,6 +195,12 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
195
195
  ...await lighthouseRunner(requestedUrl, configJson, {isDebug, useLegacyNavigation}),
196
196
  networkRequests: takeNetworkRequestUrls ? takeNetworkRequestUrls() : undefined,
197
197
  };
198
+
199
+ if (!result.lhr?.audits || !result.artifacts) {
200
+ // Something went really wrong and the runner didn't catch it.
201
+ throw new Error('lighthouse runner returned a bad result. got lhr:\n' +
202
+ JSON.stringify(result.lhr, null, 2));
203
+ }
198
204
  } catch (e) {
199
205
  // Clear the network requests so that when we retry, we don't see duplicates.
200
206
  if (takeNetworkRequestUrls) takeNetworkRequestUrls();
@@ -7,8 +7,8 @@
7
7
  import {Audit} from './audit.js';
8
8
  import {taskGroups} from '../lib/tracehouse/task-groups.js';
9
9
  import * as i18n from '../lib/i18n/i18n.js';
10
- import NetworkRecords from '../computed/network-records.js';
11
- import MainThreadTasks from '../computed/main-thread-tasks.js';
10
+ import {NetworkRecords} from '../computed/network-records.js';
11
+ import {MainThreadTasks} from '../computed/main-thread-tasks.js';
12
12
  import {getExecutionTimingsByURL} from '../lib/tracehouse/task-summary.js';
13
13
 
14
14
  const UIStrings = {
@@ -6,11 +6,11 @@
6
6
 
7
7
  import {Audit} from '../audit.js';
8
8
  import {linearInterpolation} from '../../lib/statistics.js';
9
- import Interactive from '../../computed/metrics/lantern-interactive.js';
9
+ import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
10
10
  import * as i18n from '../../lib/i18n/i18n.js';
11
- import NetworkRecords from '../../computed/network-records.js';
12
- import LoadSimulator from '../../computed/load-simulator.js';
13
- import PageDependencyGraph from '../../computed/page-dependency-graph.js';
11
+ import {NetworkRecords} from '../../computed/network-records.js';
12
+ import {LoadSimulator} from '../../computed/load-simulator.js';
13
+ import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
14
14
 
15
15
  const str_ = i18n.createIcuMessageFn(import.meta.url, {});
16
16
 
@@ -190,8 +190,9 @@ class ByteEfficiencyAudit extends Audit {
190
190
  });
191
191
 
192
192
  const savingsOnOverallLoad = simulationBeforeChanges.timeInMs - simulationAfterChanges.timeInMs;
193
- const savingsOnTTI = Interactive.getLastLongTaskEndTime(simulationBeforeChanges.nodeTimings) -
194
- Interactive.getLastLongTaskEndTime(simulationAfterChanges.nodeTimings);
193
+ const savingsOnTTI =
194
+ LanternInteractive.getLastLongTaskEndTime(simulationBeforeChanges.nodeTimings) -
195
+ LanternInteractive.getLastLongTaskEndTime(simulationAfterChanges.nodeTimings);
195
196
 
196
197
  let savings = savingsOnTTI;
197
198
  if (options.includeLoad) savings = Math.max(savings, savingsOnOverallLoad);
@@ -9,7 +9,7 @@
9
9
  /** @typedef {{url: string, sourceTransferBytes?: number}} SubItem */
10
10
 
11
11
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
12
- import ModuleDuplication from '../../computed/module-duplication.js';
12
+ import {ModuleDuplication} from '../../computed/module-duplication.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
14
  import {getRequestForScript} from '../../lib/script-helpers.js';
15
15
 
@@ -20,7 +20,7 @@
20
20
  import fs from 'fs';
21
21
 
22
22
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
23
- import JsBundles from '../../computed/js-bundles.js';
23
+ import {JSBundles} from '../../computed/js-bundles.js';
24
24
  import * as i18n from '../../lib/i18n/i18n.js';
25
25
  import thirdPartyWeb from '../../lib/third-party-web.js';
26
26
  import {getRequestForScript} from '../../lib/script-helpers.js';
@@ -402,7 +402,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
402
402
  */
403
403
  static async audit_(artifacts, networkRecords, context) {
404
404
  const mainDocumentEntity = thirdPartyWeb.getEntity(artifacts.URL.finalUrl);
405
- const bundles = await JsBundles.request(artifacts, context);
405
+ const bundles = await JSBundles.request(artifacts, context);
406
406
 
407
407
  /** @type {Item[]} */
408
408
  const items = [];
@@ -9,7 +9,7 @@
9
9
 
10
10
 
11
11
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
12
- import URL from '../../lib/url-shim.js';
12
+ import UrlUtils from '../../lib/url-utils.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
14
 
15
15
  const UIStrings = {
@@ -106,7 +106,7 @@ class ModernImageFormats extends ByteEfficiencyAudit {
106
106
  const imageElement = imageElementsByURL.get(image.url);
107
107
 
108
108
  if (image.failed) {
109
- warnings.push(`Unable to decode ${URL.getURLDisplayName(image.url)}`);
109
+ warnings.push(`Unable to decode ${UrlUtils.getURLDisplayName(image.url)}`);
110
110
  continue;
111
111
  }
112
112
 
@@ -123,7 +123,7 @@ class ModernImageFormats extends ByteEfficiencyAudit {
123
123
 
124
124
  if (typeof webpSize === 'undefined') {
125
125
  if (!imageElement) {
126
- warnings.push(`Unable to locate resource ${URL.getURLDisplayName(image.url)}`);
126
+ warnings.push(`Unable to locate resource ${UrlUtils.getURLDisplayName(image.url)}`);
127
127
  continue;
128
128
  }
129
129
 
@@ -152,8 +152,8 @@ class ModernImageFormats extends ByteEfficiencyAudit {
152
152
  const wastedBytes = image.originalSize - avifSize;
153
153
  if (wastedBytes < IGNORE_THRESHOLD_IN_BYTES) continue;
154
154
 
155
- const url = URL.elideDataURI(image.url);
156
- const isCrossOrigin = !URL.originsMatch(pageURL, image.url);
155
+ const url = UrlUtils.elideDataURI(image.url);
156
+ const isCrossOrigin = !UrlUtils.originsMatch(pageURL, image.url);
157
157
 
158
158
  items.push({
159
159
  node: imageElement ? ByteEfficiencyAudit.makeNodeItem(imageElement.node) : undefined,
@@ -12,10 +12,10 @@
12
12
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
13
13
  import {NetworkRequest} from '../../lib/network-request.js';
14
14
  import {Sentry} from '../../lib/sentry.js';
15
- import URL from '../../lib/url-shim.js';
15
+ import UrlUtils from '../../lib/url-utils.js';
16
16
  import * as i18n from '../../lib/i18n/i18n.js';
17
- import Interactive from '../../computed/metrics/interactive.js';
18
- import ProcessedTrace from '../../computed/processed-trace.js';
17
+ import {Interactive} from '../../computed/metrics/interactive.js';
18
+ import {ProcessedTrace} from '../../computed/processed-trace.js';
19
19
 
20
20
  const UIStrings = {
21
21
  /** Imperative title of a Lighthouse audit that tells the user to defer loading offscreen images. Offscreen images are images located outside of the visible browser viewport. As they are unseen by the user and slow down page load, they should be loaded later, closer to when the user is going to see them. This is displayed in a list of audit titles that Lighthouse generates. */
@@ -87,7 +87,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
87
87
  // If the image had its loading behavior explicitly controlled already, treat it as passed.
88
88
  if (image.loading === 'lazy' || image.loading === 'eager') return null;
89
89
 
90
- const url = URL.elideDataURI(image.src);
90
+ const url = UrlUtils.elideDataURI(image.src);
91
91
  const totalPixels = image.displayedWidth * image.displayedHeight;
92
92
  const visiblePixels = this.computeVisiblePixels(image.clientRect, viewportDimensions);
93
93
  // Treat images with 0 area as if they're offscreen. See https://github.com/GoogleChrome/lighthouse/issues/1914
@@ -13,12 +13,12 @@ import {Audit} from '../audit.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
14
  import {BaseNode} from '../../lib/dependency-graph/base-node.js';
15
15
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
16
- import UnusedCSS from '../../computed/unused-css.js';
16
+ import {UnusedCSS} from '../../computed/unused-css.js';
17
17
  import {NetworkRequest} from '../../lib/network-request.js';
18
- import ProcessedTrace from '../../computed/processed-trace.js';
19
- import ProcessedNavigation from '../../computed/processed-navigation.js';
20
- import LoadSimulator from '../../computed/load-simulator.js';
21
- import FirstContentfulPaint from '../../computed/metrics/first-contentful-paint.js';
18
+ import {ProcessedTrace} from '../../computed/processed-trace.js';
19
+ import {ProcessedNavigation} from '../../computed/processed-navigation.js';
20
+ import {LoadSimulator} from '../../computed/load-simulator.js';
21
+ import {FirstContentfulPaint} from '../../computed/metrics/first-contentful-paint.js';
22
22
 
23
23
  /** @typedef {import('../../lib/dependency-graph/simulator/simulator').Simulator} Simulator */
24
24
  /** @typedef {import('../../lib/dependency-graph/base-node.js').Node} Node */
@@ -7,7 +7,7 @@
7
7
  import {Audit} from '../audit.js';
8
8
  import * as i18n from '../../lib/i18n/i18n.js';
9
9
  import {NetworkRequest} from '../../lib/network-request.js';
10
- import NetworkRecords from '../../computed/network-records.js';
10
+ import {NetworkRecords} from '../../computed/network-records.js';
11
11
 
12
12
  const UIStrings = {
13
13
  /** Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
8
- import UnusedCSS from '../../computed/unused-css.js';
8
+ import {UnusedCSS} from '../../computed/unused-css.js';
9
9
  import * as i18n from '../../lib/i18n/i18n.js';
10
10
  import {computeCSSTokenLength as computeTokenLength} from '../../lib/minification-estimator.js';
11
11
 
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
8
- import UnusedCSS from '../../computed/unused-css.js';
8
+ import {UnusedCSS} from '../../computed/unused-css.js';
9
9
  import * as i18n from '../../lib/i18n/i18n.js';
10
10
 
11
11
  const UIStrings = {
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
8
- import UnusedJavaScriptSummary from '../../computed/unused-javascript-summary.js';
9
- import JsBundles from '../../computed/js-bundles.js';
8
+ import {UnusedJavascriptSummary} from '../../computed/unused-javascript-summary.js';
9
+ import {JSBundles} from '../../computed/js-bundles.js';
10
10
  import * as i18n from '../../lib/i18n/i18n.js';
11
11
  import {getRequestForScript} from '../../lib/script-helpers.js';
12
12
 
@@ -79,7 +79,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
79
79
  * @return {Promise<import('./byte-efficiency-audit.js').ByteEfficiencyProduct>}
80
80
  */
81
81
  static async audit_(artifacts, networkRecords, context) {
82
- const bundles = await JsBundles.request(artifacts, context);
82
+ const bundles = await JSBundles.request(artifacts, context);
83
83
  const {
84
84
  unusedThreshold = UNUSED_BYTES_IGNORE_THRESHOLD,
85
85
  bundleSourceUnusedThreshold = UNUSED_BYTES_IGNORE_BUNDLE_SOURCE_THRESHOLD,
@@ -95,7 +95,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
95
95
 
96
96
  const bundle = bundles.find(b => b.script.scriptId === scriptId);
97
97
  const unusedJsSummary =
98
- await UnusedJavaScriptSummary.request({scriptId, scriptCoverage, bundle}, context);
98
+ await UnusedJavascriptSummary.request({scriptId, scriptCoverage, bundle}, context);
99
99
  if (unusedJsSummary.wastedBytes === 0 || unusedJsSummary.totalBytes === 0) continue;
100
100
 
101
101
  const transfer = ByteEfficiencyAudit
@@ -8,10 +8,10 @@ import parseCacheControl from 'parse-cache-control';
8
8
 
9
9
  import {Audit} from '../audit.js';
10
10
  import {NetworkRequest} from '../../lib/network-request.js';
11
- import URL from '../../lib/url-shim.js';
11
+ import UrlUtils from '../../lib/url-utils.js';
12
12
  import {linearInterpolation} from '../../lib/statistics.js';
13
13
  import * as i18n from '../../lib/i18n/i18n.js';
14
- import NetworkRecords from '../../computed/network-records.js';
14
+ import {NetworkRecords} from '../../computed/network-records.js';
15
15
 
16
16
  const UIStrings = {
17
17
  /** Title of a diagnostic audit that provides detail on the cache policy applies to the page's static assets. Cache refers to browser disk cache, which keeps old versions of network resources around for future use. This is displayed in a list of audit titles that Lighthouse generates. */
@@ -233,7 +233,7 @@ class CacheHeaders extends Audit {
233
233
  const cacheHitProbability = CacheHeaders.getCacheHitProbability(cacheLifetimeInSeconds);
234
234
  if (cacheHitProbability > IGNORE_THRESHOLD_IN_PERCENT) continue;
235
235
 
236
- const url = URL.elideDataURI(record.url);
236
+ const url = UrlUtils.elideDataURI(record.url);
237
237
  const totalBytes = record.transferSize || 0;
238
238
  const wastedBytes = (1 - cacheHitProbability) * totalBytes;
239
239
 
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
13
- import URL from '../../lib/url-shim.js';
13
+ import UrlUtils from '../../lib/url-utils.js';
14
14
  import * as i18n from '../../lib/i18n/i18n.js';
15
15
 
16
16
  const UIStrings = {
@@ -83,7 +83,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
83
83
  const imageElement = imageElementsByURL.get(image.url);
84
84
 
85
85
  if (image.failed) {
86
- warnings.push(`Unable to decode ${URL.getURLDisplayName(image.url)}`);
86
+ warnings.push(`Unable to decode ${UrlUtils.getURLDisplayName(image.url)}`);
87
87
  continue;
88
88
  } else if (/(jpeg|bmp)/.test(image.mimeType) === false) {
89
89
  continue;
@@ -94,7 +94,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
94
94
 
95
95
  if (typeof jpegSize === 'undefined') {
96
96
  if (!imageElement) {
97
- warnings.push(`Unable to locate resource ${URL.getURLDisplayName(image.url)}`);
97
+ warnings.push(`Unable to locate resource ${UrlUtils.getURLDisplayName(image.url)}`);
98
98
  continue;
99
99
  }
100
100
 
@@ -111,8 +111,8 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
111
111
 
112
112
  if (image.originalSize < jpegSize + IGNORE_THRESHOLD_IN_BYTES) continue;
113
113
 
114
- const url = URL.elideDataURI(image.url);
115
- const isCrossOrigin = !URL.originsMatch(pageURL, image.url);
114
+ const url = UrlUtils.elideDataURI(image.url);
115
+ const isCrossOrigin = !UrlUtils.originsMatch(pageURL, image.url);
116
116
  const jpegSavings = UsesOptimizedImages.computeSavings({...image, jpegSize});
117
117
 
118
118
  items.push({
@@ -13,7 +13,7 @@
13
13
 
14
14
  import {Audit} from '../audit.js';
15
15
  import * as UsesResponsiveImages from './uses-responsive-images.js';
16
- import URL from '../../lib/url-shim.js';
16
+ import UrlUtils from '../../lib/url-utils.js';
17
17
  import * as i18n from '../../lib/i18n/i18n.js';
18
18
 
19
19
  const UIStrings = {
@@ -71,7 +71,7 @@ class UsesResponsiveImagesSnapshot extends Audit {
71
71
 
72
72
  items.push({
73
73
  node: Audit.makeNodeItem(image.node),
74
- url: URL.elideDataURI(image.src),
74
+ url: UrlUtils.elideDataURI(image.src),
75
75
  displayedDimensions: `${displayed.width}x${displayed.height}`,
76
76
  actualDimensions: `${actual.width}x${actual.height}`,
77
77
  });
@@ -15,8 +15,8 @@
15
15
 
16
16
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
17
17
  import {NetworkRequest} from '../../lib/network-request.js';
18
- import ImageRecords from '../../computed/image-records.js';
19
- import URL from '../../lib/url-shim.js';
18
+ import {ImageRecords} from '../../computed/image-records.js';
19
+ import UrlUtils from '../../lib/url-utils.js';
20
20
  import * as i18n from '../../lib/i18n/i18n.js';
21
21
 
22
22
  const UIStrings = {
@@ -100,7 +100,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
100
100
  const displayed = this.getDisplayedDimensions(image, ViewportDimensions);
101
101
  const usedPixels = displayed.width * displayed.height;
102
102
 
103
- const url = URL.elideDataURI(image.src);
103
+ const url = UrlUtils.elideDataURI(image.src);
104
104
  const actualPixels = image.naturalWidth * image.naturalHeight;
105
105
  const wastedRatio = 1 - (usedPixels / actualPixels);
106
106
  const totalBytes = NetworkRequest.getResourceSizeOnNetwork(networkRecord);
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
13
- import URL from '../../lib/url-shim.js';
13
+ import UrlUtils from '../../lib/url-utils.js';
14
14
  import * as i18n from '../../lib/i18n/i18n.js';
15
15
 
16
16
  const UIStrings = {
@@ -68,7 +68,7 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
68
68
  }
69
69
 
70
70
  // remove duplicates
71
- const url = URL.elideDataURI(record.url);
71
+ const url = UrlUtils.elideDataURI(record.url);
72
72
  const isDuplicate = items.find(item => item.url === url &&
73
73
  item.totalBytes === record.resourceSize);
74
74
  if (isDuplicate) {
@@ -6,7 +6,7 @@
6
6
 
7
7
  import {Audit} from './audit.js';
8
8
  import * as i18n from '../lib/i18n/i18n.js';
9
- import ComputedChains from '../computed/critical-request-chains.js';
9
+ import {CriticalRequestChains as ComputedChains} from '../computed/critical-request-chains.js';
10
10
 
11
11
  const UIStrings = {
12
12
  /** Imperative title of a Lighthouse audit that tells the user to reduce the depth of critical network requests to enhance initial load of a page. Critical request chains are series of dependent network requests that are important for page rendering. For example, here's a 4-request-deep chain: The biglogo.jpg image is required, but is requested via the styles.css style code, which is requested by the initialize.js javascript, which is requested by the page's HTML. This is displayed in a list of audit titles that Lighthouse generates. */
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import {Audit} from './audit.js';
8
- import MainResource from '../computed/main-resource.js';
8
+ import {MainResource} from '../computed/main-resource.js';
9
9
  import * as i18n from '../lib/i18n/i18n.js';
10
10
  import {evaluateRawCspsForXss, getTranslatedDescription} from '../lib/csp-evaluator.js';
11
11
 
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import {Audit} from './audit.js';
12
- import JsBundles from '../computed/js-bundles.js';
12
+ import {JSBundles} from '../computed/js-bundles.js';
13
13
  import * as i18n from '../lib/i18n/i18n.js';
14
14
  import {getIssueDetailDescription} from '../lib/deprecations-strings.js';
15
15
 
@@ -56,7 +56,7 @@ class Deprecations extends Audit {
56
56
  * @return {Promise<LH.Audit.Product>}
57
57
  */
58
58
  static async audit(artifacts, context) {
59
- const bundles = await JsBundles.request(artifacts, context);
59
+ const bundles = await JSBundles.request(artifacts, context);
60
60
 
61
61
  const deprecations = artifacts.InspectorIssues.deprecationIssue
62
62
  .map(deprecation => {
@@ -5,10 +5,10 @@
5
5
  */
6
6
 
7
7
  import {Audit} from './audit.js';
8
- import MainThreadTasksComputed from '../computed/main-thread-tasks.js';
9
- import NetworkRecordsComputed from '../computed/network-records.js';
10
- import NetworkAnalysisComputed from '../computed/network-analysis.js';
11
- import MainResource from '../computed/main-resource.js';
8
+ import {MainThreadTasks} from '../computed/main-thread-tasks.js';
9
+ import {NetworkRecords} from '../computed/network-records.js';
10
+ import {NetworkAnalysis} from '../computed/network-analysis.js';
11
+ import {MainResource} from '../computed/main-resource.js';
12
12
 
13
13
  class Diagnostics extends Audit {
14
14
  /**
@@ -33,9 +33,9 @@ class Diagnostics extends Audit {
33
33
  static async audit(artifacts, context) {
34
34
  const trace = artifacts.traces[Audit.DEFAULT_PASS];
35
35
  const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
36
- const tasks = await MainThreadTasksComputed.request(trace, context);
37
- const records = await NetworkRecordsComputed.request(devtoolsLog, context);
38
- const analysis = await NetworkAnalysisComputed.request(devtoolsLog, context);
36
+ const tasks = await MainThreadTasks.request(trace, context);
37
+ const records = await NetworkRecords.request(devtoolsLog, context);
38
+ const analysis = await NetworkAnalysis.request(devtoolsLog, context);
39
39
  const mainResource = await MainResource.request({devtoolsLog, URL: artifacts.URL}, context);
40
40
 
41
41
  const toplevelTasks = tasks.filter(t => !t.parent);
@@ -14,7 +14,7 @@
14
14
 
15
15
  import {Audit} from '../audit.js';
16
16
  import * as i18n from '../../lib/i18n/i18n.js';
17
- import MainResource from '../../computed/main-resource.js';
17
+ import {MainResource} from '../../computed/main-resource.js';
18
18
 
19
19
  const UIStrings = {
20
20
  /** Title of a Lighthouse audit that provides detail on if the charset is set properly for a page. This title is shown when the charset is defined correctly. Charset defines the character encoding (eg UTF-8) of the page content. */
@@ -14,13 +14,13 @@
14
14
 
15
15
  import {Audit} from '../audit.js';
16
16
  import ThirdParty from '../../lib/third-party-web.js';
17
- import URL from '../../lib/url-shim.js';
17
+ import UrlUtils from '../../lib/url-utils.js';
18
18
  import {ByteEfficiencyAudit} from '../byte-efficiency/byte-efficiency-audit.js';
19
- import Interactive from '../../computed/metrics/lantern-interactive.js';
19
+ import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
20
20
  import {NetworkRequest} from '../../lib/network-request.js';
21
- import NetworkRecords from '../../computed/network-records.js';
22
- import LoadSimulator from '../../computed/load-simulator.js';
23
- import PageDependencyGraph from '../../computed/page-dependency-graph.js';
21
+ import {NetworkRecords} from '../../computed/network-records.js';
22
+ import {LoadSimulator} from '../../computed/load-simulator.js';
23
+ import {PageDependencyGraph} from '../../computed/page-dependency-graph.js';
24
24
  import * as i18n from '../../lib/i18n/i18n.js';
25
25
 
26
26
  const UIStrings = {
@@ -106,8 +106,8 @@ class UsesHTTP2Audit extends Audit {
106
106
  });
107
107
 
108
108
  const savingsOnOverallLoad = simulationBefore.timeInMs - simulationAfter.timeInMs;
109
- const savingsOnTTI = Interactive.getLastLongTaskEndTime(simulationBefore.nodeTimings) -
110
- Interactive.getLastLongTaskEndTime(simulationAfter.nodeTimings);
109
+ const savingsOnTTI = LanternInteractive.getLastLongTaskEndTime(simulationBefore.nodeTimings) -
110
+ LanternInteractive.getLastLongTaskEndTime(simulationAfter.nodeTimings);
111
111
  const savings = Math.max(savingsOnTTI, savingsOnOverallLoad);
112
112
 
113
113
  // Round waste to nearest 10ms
@@ -167,7 +167,7 @@ class UsesHTTP2Audit extends Audit {
167
167
  const groupedByOrigin = new Map();
168
168
  for (const record of networkRecords) {
169
169
  if (!UsesHTTP2Audit.isStaticAsset(record)) continue;
170
- if (URL.isLikeLocalhost(record.parsedURL.host)) continue;
170
+ if (UrlUtils.isLikeLocalhost(record.parsedURL.host)) continue;
171
171
  const existing = groupedByOrigin.get(record.parsedURL.securityOrigin) || [];
172
172
  existing.push(record);
173
173
  groupedByOrigin.set(record.parsedURL.securityOrigin, existing);
@@ -12,7 +12,7 @@
12
12
  import log from 'lighthouse-logger';
13
13
 
14
14
  import {Audit} from './audit.js';
15
- import JsBundles from '../computed/js-bundles.js';
15
+ import {JSBundles} from '../computed/js-bundles.js';
16
16
  import * as i18n from '../lib/i18n/i18n.js';
17
17
 
18
18
  const UIStrings = {
@@ -81,7 +81,7 @@ class ErrorLogs extends Audit {
81
81
  static async audit(artifacts, context) {
82
82
  /** @type {AuditOptions} */
83
83
  const auditOptions = context.options;
84
- const bundles = await JsBundles.request(artifacts, context);
84
+ const bundles = await JSBundles.request(artifacts, context);
85
85
 
86
86
  /** @type {Array<{source: string, description: string|undefined, sourceLocation: LH.Audit.Details.SourceLocationValue|undefined}>} */
87
87
  const consoleRows = artifacts.ConsoleMessages
@@ -6,8 +6,8 @@
6
6
 
7
7
  import {Audit} from './audit.js';
8
8
  import {LighthouseError} from '../lib/lh-error.js';
9
- import ProcessedTrace from '../computed/processed-trace.js';
10
- import Screenshots from '../computed/screenshots.js';
9
+ import {ProcessedTrace} from '../computed/processed-trace.js';
10
+ import {Screenshots} from '../computed/screenshots.js';
11
11
 
12
12
  class FinalScreenshot extends Audit {
13
13
  /**
@@ -5,13 +5,14 @@
5
5
  */
6
6
 
7
7
  import {Audit} from './audit.js';
8
- import URL from '../lib/url-shim.js';
8
+ import UrlUtils from '../lib/url-utils.js';
9
+ import * as i18n from '../lib/i18n/i18n.js';
10
+ import {Sentry} from '../lib/sentry.js';
11
+ import {NetworkRecords} from '../computed/network-records.js';
12
+
9
13
  const PASSING_FONT_DISPLAY_REGEX = /^(block|fallback|optional|swap)$/;
10
14
  const CSS_URL_REGEX = /url\((.*?)\)/;
11
15
  const CSS_URL_GLOBAL_REGEX = new RegExp(CSS_URL_REGEX, 'g');
12
- import * as i18n from '../lib/i18n/i18n.js';
13
- import {Sentry} from '../lib/sentry.js';
14
- import NetworkRecords from '../computed/network-records.js';
15
16
 
16
17
  const UIStrings = {
17
18
  /** Title of a diagnostic audit that provides detail on if all the text on a webpage was visible while the page was loading its webfonts. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
@@ -98,7 +99,7 @@ class FontDisplay extends Audit {
98
99
  // Convert the relative CSS URL to an absolute URL and add it to the target set.
99
100
  for (const relativeURL of relativeURLs) {
100
101
  try {
101
- const relativeRoot = URL.isValid(stylesheet.header.sourceURL) ?
102
+ const relativeRoot = UrlUtils.isValid(stylesheet.header.sourceURL) ?
102
103
  stylesheet.header.sourceURL : artifacts.URL.finalUrl;
103
104
  const absoluteURL = new URL(relativeURL, relativeRoot);
104
105
  targetURLSet.add(absoluteURL.href);
@@ -121,7 +122,7 @@ class FontDisplay extends Audit {
121
122
  /** @type {Map<string, number>} */
122
123
  const warningCountByOrigin = new Map();
123
124
  for (const warningUrl of warningUrls) {
124
- const origin = URL.getOrigin(warningUrl);
125
+ const origin = UrlUtils.getOrigin(warningUrl);
125
126
  if (!origin) continue;
126
127
 
127
128
  const count = warningCountByOrigin.get(origin) || 0;