lighthouse 9.5.0-dev.20220328 → 9.5.0-dev.20220331

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 (75) hide show
  1. package/dist/report/bundle.esm.js +20 -18
  2. package/dist/report/flow.js +1 -1
  3. package/dist/report/standalone.js +1 -1
  4. package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +28 -18
  5. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +2 -1
  6. package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  7. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +3 -2
  8. package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +1 -1
  9. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +1 -1
  10. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
  11. package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
  12. package/lighthouse-core/audits/dobetterweb/uses-http2.js +2 -1
  13. package/lighthouse-core/audits/long-tasks.js +3 -2
  14. package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
  15. package/lighthouse-core/audits/metrics/first-contentful-paint.js +3 -2
  16. package/lighthouse-core/audits/metrics/first-meaningful-paint.js +3 -2
  17. package/lighthouse-core/audits/metrics/interactive.js +3 -2
  18. package/lighthouse-core/audits/metrics/largest-contentful-paint.js +3 -2
  19. package/lighthouse-core/audits/metrics/max-potential-fid.js +3 -2
  20. package/lighthouse-core/audits/metrics/speed-index.js +3 -2
  21. package/lighthouse-core/audits/metrics/total-blocking-time.js +3 -2
  22. package/lighthouse-core/audits/metrics.js +3 -2
  23. package/lighthouse-core/audits/predictive-perf.js +2 -1
  24. package/lighthouse-core/audits/preload-lcp-image.js +3 -3
  25. package/lighthouse-core/audits/redirects.js +1 -1
  26. package/lighthouse-core/audits/script-treemap-data.js +31 -32
  27. package/lighthouse-core/audits/timing-budget.js +3 -2
  28. package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
  29. package/lighthouse-core/audits/uses-rel-preload.js +1 -1
  30. package/lighthouse-core/computed/critical-request-chains.js +2 -9
  31. package/lighthouse-core/computed/main-resource.js +1 -1
  32. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
  33. package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
  34. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
  35. package/lighthouse-core/computed/metrics/interactive.js +1 -1
  36. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
  37. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
  38. package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
  39. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
  40. package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
  41. package/lighthouse-core/computed/metrics/lantern-metric.js +3 -5
  42. package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
  43. package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
  44. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
  45. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
  46. package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
  47. package/lighthouse-core/computed/metrics/metric.js +1 -0
  48. package/lighthouse-core/computed/metrics/speed-index.js +1 -1
  49. package/lighthouse-core/computed/metrics/timing-summary.js +13 -6
  50. package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
  51. package/lighthouse-core/computed/page-dependency-graph.js +54 -31
  52. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +8 -1
  53. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +32 -22
  54. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +0 -3
  55. package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +6 -3
  56. package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +7 -5
  57. package/lighthouse-core/gather/connections/cri.js +1 -0
  58. package/lighthouse-core/gather/driver/execution-context.js +4 -2
  59. package/lighthouse-core/gather/driver/navigation.js +9 -9
  60. package/lighthouse-core/gather/driver/network-monitor.js +16 -3
  61. package/lighthouse-core/gather/driver.js +5 -0
  62. package/lighthouse-core/gather/gather-runner.js +13 -7
  63. package/lighthouse-core/gather/gatherers/js-usage.js +7 -6
  64. package/lighthouse-core/gather/gatherers/scripts.js +20 -2
  65. package/lighthouse-core/gather/gatherers/seo/robots-txt.js +2 -1
  66. package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
  67. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +8 -29
  68. package/lighthouse-core/lib/navigation-error.js +13 -4
  69. package/lighthouse-core/util-commonjs.js +20 -18
  70. package/package.json +3 -3
  71. package/report/renderer/util.js +20 -18
  72. package/shared/localization/locales/en-US.json +1 -1
  73. package/shared/localization/locales/en-XL.json +1 -1
  74. package/types/artifacts.d.ts +25 -2
  75. package/types/gatherer.d.ts +1 -2
@@ -6,7 +6,6 @@
6
6
  'use strict';
7
7
 
8
8
  const INITIAL_CWD = 14 * 1024;
9
- const NetworkRequest = require('../../network-request.js');
10
9
  const URL = require('../../url-shim.js');
11
10
 
12
11
  // Assume that 40% of TTFB was server response time by default for static assets
@@ -434,40 +433,20 @@ class NetworkAnalyzer {
434
433
 
435
434
  /**
436
435
  * @param {Array<LH.Artifacts.NetworkRequest>} records
437
- * @param {string} [finalURL]
438
- * @return {LH.Artifacts.NetworkRequest}
439
- */
440
- static findMainDocument(records, finalURL) {
441
- const mainDocument = NetworkAnalyzer.findOptionalMainDocument(records, finalURL);
442
- if (!mainDocument) throw new Error('Unable to identify the main resource');
443
- return mainDocument;
444
- }
445
-
446
- /**
447
- * @param {Array<LH.Artifacts.NetworkRequest>} records
448
- * @param {string} [finalURL]
436
+ * @param {string} resourceUrl
449
437
  * @return {LH.Artifacts.NetworkRequest|undefined}
450
438
  */
451
- static findOptionalMainDocument(records, finalURL) {
452
- // Try to find an exact match with the final URL first if we have one
453
- if (finalURL) {
454
- // equalWithExcludedFragments is expensive, so check that the finalUrl starts with the request first
455
- const mainResource = records.find(request => finalURL.startsWith(request.url) &&
456
- URL.equalWithExcludedFragments(request.url, finalURL));
457
- if (mainResource) return mainResource;
458
- // TODO: beacon !mainResource to Sentry, https://github.com/GoogleChrome/lighthouse/issues/7041
459
- }
460
-
461
- const documentRequests = records.filter(record => record.resourceType ===
462
- NetworkRequest.TYPES.Document);
463
- if (!documentRequests.length) return undefined;
464
- // The main document is the earliest document request, using position in networkRecords array to break ties.
465
- return documentRequests.reduce((min, r) => (r.startTime < min.startTime ? r : min));
439
+ static findResourceForUrl(records, resourceUrl) {
440
+ // equalWithExcludedFragments is expensive, so check that the resourceUrl starts with the request url first
441
+ return records.find(request =>
442
+ resourceUrl.startsWith(request.url) &&
443
+ URL.equalWithExcludedFragments(request.url, resourceUrl)
444
+ );
466
445
  }
467
446
 
468
447
  /**
469
448
  * Resolves redirect chain given a main document.
470
- * See: {@link NetworkAnalyzer.findMainDocument}) for how to retrieve main document.
449
+ * See: {@link NetworkAnalyzer.findResourceForUrl}) for how to retrieve main document.
471
450
  *
472
451
  * @param {LH.Artifacts.NetworkRequest} request
473
452
  * @return {LH.Artifacts.NetworkRequest}
@@ -7,6 +7,7 @@
7
7
 
8
8
  const LHError = require('./lh-error.js');
9
9
  const NetworkAnalyzer = require('./dependency-graph/simulator/network-analyzer.js');
10
+ const NetworkRequest = require('./network-request.js');
10
11
 
11
12
  /**
12
13
  * Returns an error if the original network request failed or wasn't found.
@@ -100,10 +101,18 @@ function getNonHtmlError(finalRecord) {
100
101
  function getPageLoadError(navigationError, context) {
101
102
  const {url, loadFailureMode, networkRecords} = context;
102
103
  /** @type {LH.Artifacts.NetworkRequest|undefined} */
103
- let mainRecord;
104
- try {
105
- mainRecord = NetworkAnalyzer.findMainDocument(networkRecords, url);
106
- } catch (_) {}
104
+ let mainRecord = NetworkAnalyzer.findResourceForUrl(networkRecords, url);
105
+
106
+ // If the url doesn't give us a network request, it's possible we landed on a chrome-error:// page
107
+ // In this case, just get the first document request.
108
+ if (!mainRecord) {
109
+ const documentRequests = networkRecords.filter(record =>
110
+ record.resourceType === NetworkRequest.TYPES.Document
111
+ );
112
+ if (documentRequests.length) {
113
+ mainRecord = documentRequests.reduce((min, r) => (r.startTime < min.startTime ? r : min));
114
+ }
115
+ }
107
116
 
108
117
  // MIME Type is only set on the final redirected document request. Use this for the HTML check instead of root.
109
118
  let finalRecord;
@@ -318,24 +318,26 @@ class Util {
318
318
  }
319
319
 
320
320
  const MAX_LENGTH = 64;
321
- // Always elide hexadecimal hash
322
- name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
323
- // Also elide other hash-like mixed-case strings
324
- name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
325
- `$1${ELLIPSIS}`);
326
- // Also elide long number sequences
327
- name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
328
- // Merge any adjacent ellipses
329
- name = name.replace(/\u2026+/g, ELLIPSIS);
330
-
331
- // Elide query params first
332
- if (name.length > MAX_LENGTH && name.includes('?')) {
333
- // Try to leave the first query parameter intact
334
- name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
335
-
336
- // Remove it all if it's still too long
337
- if (name.length > MAX_LENGTH) {
338
- name = name.replace(/\?.*/, `?${ELLIPSIS}`);
321
+ if (parsedUrl.protocol !== 'data:') {
322
+ // Always elide hexadecimal hash
323
+ name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
324
+ // Also elide other hash-like mixed-case strings
325
+ name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
326
+ `$1${ELLIPSIS}`);
327
+ // Also elide long number sequences
328
+ name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
329
+ // Merge any adjacent ellipses
330
+ name = name.replace(/\u2026+/g, ELLIPSIS);
331
+
332
+ // Elide query params first
333
+ if (name.length > MAX_LENGTH && name.includes('?')) {
334
+ // Try to leave the first query parameter intact
335
+ name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
336
+
337
+ // Remove it all if it's still too long
338
+ if (name.length > MAX_LENGTH) {
339
+ name = name.replace(/\?.*/, `?${ELLIPSIS}`);
340
+ }
339
341
  }
340
342
  }
341
343
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lighthouse",
3
- "version": "9.5.0-dev.20220328",
3
+ "version": "9.5.0-dev.20220331",
4
4
  "description": "Automated auditing, performance metrics, and best practices for the web.",
5
5
  "main": "./lighthouse-core/index.js",
6
6
  "bin": {
@@ -89,8 +89,8 @@
89
89
  "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf ≥ 3.7.1 to compile the proto file.\" && false)",
90
90
  "build-proto-roundtrip": "mkdir -p .tmp && cross-env PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2 python proto/scripts/json_roundtrip_via_proto.py",
91
91
  "static-server": "node lighthouse-cli/test/fixtures/static-server.js",
92
- "serve-dist": "cd dist && python -m SimpleHTTPServer",
93
- "serve-gh-pages": "cd dist/gh-pages && python -m SimpleHTTPServer",
92
+ "serve-dist": "cd dist && python3 -m http.server",
93
+ "serve-gh-pages": "cd dist/gh-pages && python3 -m http.server",
94
94
  "serve-treemap": "yarn serve-gh-pages",
95
95
  "serve-viewer": "yarn serve-gh-pages",
96
96
  "flow-report": "yarn build-report --flow && node ./lighthouse-core/scripts/build-test-flow-report.js"
@@ -315,24 +315,26 @@ class Util {
315
315
  }
316
316
 
317
317
  const MAX_LENGTH = 64;
318
- // Always elide hexadecimal hash
319
- name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
320
- // Also elide other hash-like mixed-case strings
321
- name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
322
- `$1${ELLIPSIS}`);
323
- // Also elide long number sequences
324
- name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
325
- // Merge any adjacent ellipses
326
- name = name.replace(/\u2026+/g, ELLIPSIS);
327
-
328
- // Elide query params first
329
- if (name.length > MAX_LENGTH && name.includes('?')) {
330
- // Try to leave the first query parameter intact
331
- name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
332
-
333
- // Remove it all if it's still too long
334
- if (name.length > MAX_LENGTH) {
335
- name = name.replace(/\?.*/, `?${ELLIPSIS}`);
318
+ if (parsedUrl.protocol !== 'data:') {
319
+ // Always elide hexadecimal hash
320
+ name = name.replace(/([a-f0-9]{7})[a-f0-9]{13}[a-f0-9]*/g, `$1${ELLIPSIS}`);
321
+ // Also elide other hash-like mixed-case strings
322
+ name = name.replace(/([a-zA-Z0-9-_]{9})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9-_]{10,}/g,
323
+ `$1${ELLIPSIS}`);
324
+ // Also elide long number sequences
325
+ name = name.replace(/(\d{3})\d{6,}/g, `$1${ELLIPSIS}`);
326
+ // Merge any adjacent ellipses
327
+ name = name.replace(/\u2026+/g, ELLIPSIS);
328
+
329
+ // Elide query params first
330
+ if (name.length > MAX_LENGTH && name.includes('?')) {
331
+ // Try to leave the first query parameter intact
332
+ name = name.replace(/\?([^=]*)(=)?.*/, `?$1$2${ELLIPSIS}`);
333
+
334
+ // Remove it all if it's still too long
335
+ if (name.length > MAX_LENGTH) {
336
+ name = name.replace(/\?.*/, `?${ELLIPSIS}`);
337
+ }
336
338
  }
337
339
  }
338
340
 
@@ -1272,7 +1272,7 @@
1272
1272
  "message": "Fonts with `font-display: optional` are preloaded"
1273
1273
  },
1274
1274
  "lighthouse-core/audits/preload-lcp-image.js | description": {
1275
- "message": "Preload the image used by the LCP element in order to improve your LCP time. [Learn more](https://web.dev/optimize-lcp/#preload-important-resources)."
1275
+ "message": "If the LCP element is dynamically added to the page, you should preload the image in order to improve LCP. [Learn more](https://web.dev/optimize-lcp/#preload-important-resources)."
1276
1276
  },
1277
1277
  "lighthouse-core/audits/preload-lcp-image.js | title": {
1278
1278
  "message": "Preload Largest Contentful Paint image"
@@ -1272,7 +1272,7 @@
1272
1272
  "message": "F̂ón̂t́ŝ ẃît́ĥ `font-display: optional` ár̂é p̂ŕêĺôád̂éd̂"
1273
1273
  },
1274
1274
  "lighthouse-core/audits/preload-lcp-image.js | description": {
1275
- "message": "P̂ŕêĺôád̂ t́ĥé îḿâǵê úŝéd̂ b́ŷ t́ĥé L̂ĆP̂ él̂ém̂én̂t́ îń ôŕd̂ér̂ t́ô ím̂ṕr̂óv̂é ŷóûŕ L̂ĆP̂ t́îḿê. [Ĺêár̂ń m̂ór̂é](https://web.dev/optimize-lcp/#preload-important-resources)."
1275
+ "message": "Îf́ t̂h́ ĹĈṔ êĺêêń íŝ d́ŷńâîćĺl̂ âd́d̂éd̂ t́ô t́ĥé p̂áĝé, ŷóû śĥóûĺd̂ ṕr̂él̂óâd́ t̂h́ê ím̂áĝé îń ôŕd̂ér̂ t́ô ím̂ṕr̂óv̂é L̂ĆP̂. [Ĺêár̂ń m̂ór̂é](https://web.dev/optimize-lcp/#preload-important-resources)."
1276
1276
  },
1277
1277
  "lighthouse-core/audits/preload-lcp-image.js | title": {
1278
1278
  "message": "P̂ŕêĺôád̂ Ĺâŕĝéŝt́ Ĉón̂t́êńt̂f́ûĺ P̂áîńt̂ ím̂áĝé"
@@ -66,7 +66,7 @@ interface UniversalBaseArtifacts {
66
66
  */
67
67
  interface ContextualBaseArtifacts {
68
68
  /** The URL initially requested and the post-redirects URL that was actually loaded. */
69
- URL: {requestedUrl: string, finalUrl: string};
69
+ URL: Artifacts.URL;
70
70
  /** If loading the page failed, value is the error that caused it. Otherwise null. */
71
71
  PageLoadError: LighthouseError | null;
72
72
  }
@@ -187,6 +187,28 @@ declare module Artifacts {
187
187
  type TaskNode = _TaskNode;
188
188
  type MetaElement = Artifacts['MetaElements'][0];
189
189
 
190
+ interface URL {
191
+ /** URL of the main frame before Lighthouse starts. */
192
+ initialUrl: string;
193
+ /**
194
+ * URL of the first document request during a Lighthouse navigation.
195
+ * Will be the same as `initialUrl` in timespan/snapshot.
196
+ * TODO: Make this property `undefined` in timespan/snapshot.
197
+ */
198
+ requestedUrl: string;
199
+ /**
200
+ * URL of the last document request during a Lighthouse navigation.
201
+ * Will be `undefined` in timespan/snapshot.
202
+ */
203
+ mainDocumentUrl?: string;
204
+ /**
205
+ * Will be the same as `mainDocumentUrl` in navigation mode.
206
+ * Wil be the URL of the main frame after Lighthouse finishes in timespan/snapshot.
207
+ * TODO: Use the main frame URL in navigation mode as well.
208
+ */
209
+ finalUrl: string;
210
+ }
211
+
190
212
  interface NodeDetails {
191
213
  lhId: string,
192
214
  devtoolsNodePath: string,
@@ -299,7 +321,7 @@ declare module Artifacts {
299
321
  url: string;
300
322
  content?: string;
301
323
  }
302
-
324
+
303
325
  interface ScriptElement {
304
326
  type: string | null
305
327
  src: string | null
@@ -619,6 +641,7 @@ declare module Artifacts {
619
641
  settings: Immutable<Config.Settings>;
620
642
  gatherContext: Artifacts['GatherContext'];
621
643
  simulator?: InstanceType<typeof LanternSimulator>;
644
+ URL: Artifacts['URL'];
622
645
  }
623
646
 
624
647
  interface MetricComputationData extends MetricComputationDataInput {
@@ -42,12 +42,11 @@ declare module Gatherer {
42
42
  defaultSession: FRProtocolSession;
43
43
  executionContext: ExecutionContext;
44
44
  fetcher: Fetcher;
45
+ url: () => Promise<string>;
45
46
  }
46
47
 
47
48
  /** The limited context interface shared between pre and post Fraggle Rock Lighthouse. */
48
49
  interface FRTransitionalContext<TDependencies extends DependencyKey = DefaultDependenciesKey> {
49
- /** The URL of the page that is currently active. Might be `about:blank` in the before phases */
50
- url: string;
51
50
  /** The gather mode Lighthouse is currently in. */
52
51
  gatherMode: GatherMode;
53
52
  /** The connection to the page being analyzed. */