lighthouse 10.0.1-dev.20230227 → 10.0.2

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.
@@ -25,6 +25,8 @@ const exclusions = {
25
25
  'metrics-tricky-tti', 'metrics-tricky-tti-late-fcp', 'screenshot',
26
26
  // Disabled because of differences that need further investigation
27
27
  'byte-efficiency', 'byte-gzip', 'perf-preload',
28
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1420418
29
+ 'issues-mixed-content',
28
30
  ],
29
31
  };
30
32
 
@@ -4,19 +4,19 @@ declare class Redirects extends Audit {
4
4
  * This method generates the document request chain including client-side and server-side redirects.
5
5
  *
6
6
  * Example:
7
- * GET /initialUrl => 302 /firstRedirect
7
+ * GET /requestedUrl => 302 /firstRedirect
8
8
  * GET /firstRedirect => 200 /firstRedirect, window.location = '/secondRedirect'
9
9
  * GET /secondRedirect => 302 /thirdRedirect
10
- * GET /thirdRedirect => 200 /mainDocumentUrl
10
+ * GET /thirdRedirect => 302 /mainDocumentUrl
11
+ * GET /mainDocumentUrl => 200 /mainDocumentUrl
11
12
  *
12
- * Returns network records [/initialUrl, /firstRedirect, /secondRedirect, /thirdRedirect, /mainDocumentUrl]
13
+ * Returns network records [/requestedUrl, /firstRedirect, /secondRedirect, /thirdRedirect, /mainDocumentUrl]
13
14
  *
14
- * @param {LH.Artifacts.NetworkRequest} mainResource
15
15
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
16
16
  * @param {LH.Artifacts.ProcessedTrace} processedTrace
17
17
  * @return {Array<LH.Artifacts.NetworkRequest>}
18
18
  */
19
- static getDocumentRequestChain(mainResource: LH.Artifacts.NetworkRequest, networkRecords: Array<LH.Artifacts.NetworkRequest>, processedTrace: LH.Artifacts.ProcessedTrace): Array<LH.Artifacts.NetworkRequest>;
19
+ static getDocumentRequestChain(networkRecords: Array<LH.Artifacts.NetworkRequest>, processedTrace: LH.Artifacts.ProcessedTrace): Array<LH.Artifacts.NetworkRequest>;
20
20
  /**
21
21
  * @param {LH.Artifacts} artifacts
22
22
  * @param {LH.Audit.Context} context
@@ -9,7 +9,6 @@ import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
9
9
  import * as i18n from '../lib/i18n/i18n.js';
10
10
  import {ProcessedTrace} from '../computed/processed-trace.js';
11
11
  import {NetworkRecords} from '../computed/network-records.js';
12
- import {MainResource} from '../computed/main-resource.js';
13
12
  import {LanternInteractive} from '../computed/metrics/lantern-interactive.js';
14
13
 
15
14
  const UIStrings = {
@@ -40,19 +39,19 @@ class Redirects extends Audit {
40
39
  * This method generates the document request chain including client-side and server-side redirects.
41
40
  *
42
41
  * Example:
43
- * GET /initialUrl => 302 /firstRedirect
42
+ * GET /requestedUrl => 302 /firstRedirect
44
43
  * GET /firstRedirect => 200 /firstRedirect, window.location = '/secondRedirect'
45
44
  * GET /secondRedirect => 302 /thirdRedirect
46
- * GET /thirdRedirect => 200 /mainDocumentUrl
45
+ * GET /thirdRedirect => 302 /mainDocumentUrl
46
+ * GET /mainDocumentUrl => 200 /mainDocumentUrl
47
47
  *
48
- * Returns network records [/initialUrl, /firstRedirect, /secondRedirect, /thirdRedirect, /mainDocumentUrl]
48
+ * Returns network records [/requestedUrl, /firstRedirect, /secondRedirect, /thirdRedirect, /mainDocumentUrl]
49
49
  *
50
- * @param {LH.Artifacts.NetworkRequest} mainResource
51
50
  * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
52
51
  * @param {LH.Artifacts.ProcessedTrace} processedTrace
53
52
  * @return {Array<LH.Artifacts.NetworkRequest>}
54
53
  */
55
- static getDocumentRequestChain(mainResource, networkRecords, processedTrace) {
54
+ static getDocumentRequestChain(networkRecords, processedTrace) {
56
55
  /** @type {Array<LH.Artifacts.NetworkRequest>} */
57
56
  const documentRequests = [];
58
57
 
@@ -63,18 +62,19 @@ class Redirects extends Audit {
63
62
  const data = event.args.data || {};
64
63
  if (!data.documentLoaderURL || !data.isLoadingMainFrame) continue;
65
64
 
66
- let networkRecord = networkRecords.find(record => record.url === data.documentLoaderURL);
65
+ let networkRecord = networkRecords.find(record => record.requestId === data.navigationId);
67
66
  while (networkRecord) {
68
67
  documentRequests.push(networkRecord);
68
+ // HTTP redirects won't have separate navStarts, so find through the redirect chain.
69
69
  networkRecord = networkRecord.redirectDestination;
70
70
  }
71
71
  }
72
72
 
73
- // If we found documents in the trace, just use this directly.
74
- if (documentRequests.length) return documentRequests;
73
+ if (!documentRequests.length) {
74
+ throw new Error('No navigation requests found');
75
+ }
75
76
 
76
- // Use the main resource as a backup if we didn't find any modern navigationStart events
77
- return (mainResource.redirects || []).concat(mainResource);
77
+ return documentRequests;
78
78
  }
79
79
 
80
80
  /**
@@ -90,21 +90,19 @@ class Redirects extends Audit {
90
90
 
91
91
  const processedTrace = await ProcessedTrace.request(trace, context);
92
92
  const networkRecords = await NetworkRecords.request(devtoolsLog, context);
93
- const mainResource = await MainResource.request({URL: artifacts.URL, devtoolsLog}, context);
94
93
 
95
94
  const metricComputationData = {trace, devtoolsLog, gatherContext, settings, URL: artifacts.URL};
96
95
  const metricResult = await LanternInteractive.request(metricComputationData, context);
97
96
 
98
97
  /** @type {Map<string, LH.Gatherer.Simulation.NodeTiming>} */
99
- const nodeTimingsByUrl = new Map();
98
+ const nodeTimingsById = new Map();
100
99
  for (const [node, timing] of metricResult.pessimisticEstimate.nodeTimings.entries()) {
101
100
  if (node.type === 'network') {
102
- nodeTimingsByUrl.set(node.record.url, timing);
101
+ nodeTimingsById.set(node.record.requestId, timing);
103
102
  }
104
103
  }
105
104
 
106
- const documentRequests = Redirects.getDocumentRequestChain(
107
- mainResource, networkRecords, processedTrace);
105
+ const documentRequests = Redirects.getDocumentRequestChain(networkRecords, processedTrace);
108
106
 
109
107
  let totalWastedMs = 0;
110
108
  const tableRows = [];
@@ -118,8 +116,8 @@ class Redirects extends Audit {
118
116
  const initialRequest = documentRequests[i];
119
117
  const redirectedRequest = documentRequests[i + 1] || initialRequest;
120
118
 
121
- const initialTiming = nodeTimingsByUrl.get(initialRequest.url);
122
- const redirectedTiming = nodeTimingsByUrl.get(redirectedRequest.url);
119
+ const initialTiming = nodeTimingsById.get(initialRequest.requestId);
120
+ const redirectedTiming = nodeTimingsById.get(redirectedRequest.requestId);
123
121
  if (!initialTiming || !redirectedTiming) {
124
122
  throw new Error('Could not find redirects in graph');
125
123
  }
@@ -488,21 +488,24 @@ class TraceProcessor {
488
488
  * @return {Map<number, number>} Map where keys are process IDs and their values are thread IDs
489
489
  */
490
490
  static findMainFramePidTids(mainFrameInfo, keyEvents) {
491
- const frameCommittedEvts = keyEvents.filter(evt =>
492
- evt.name === 'FrameCommittedInBrowser' &&
493
- evt.args?.data?.frame === mainFrameInfo.frameId
491
+ const frameProcessEvts = keyEvents.filter(evt =>
492
+ // ProcessReadyInBrowser is used when a processID isn't available when the FrameCommittedInBrowser trace event is emitted.
493
+ // In that case. FrameCommittedInBrowser has no processId, but a processPseudoId. and the ProcessReadyInBrowser event declares the proper processId.
494
+ (evt.name === 'FrameCommittedInBrowser' || evt.name === 'ProcessReadyInBrowser') &&
495
+ evt.args?.data?.frame === mainFrameInfo.frameId &&
496
+ evt?.args?.data?.processId
494
497
  );
495
498
 
496
499
  // "Modern" traces with a navigation have a FrameCommittedInBrowser event
497
- const mainFramePids = frameCommittedEvts.length
498
- ? frameCommittedEvts.map(e => e?.args?.data?.processId)
500
+ const mainFramePids = frameProcessEvts.length
501
+ ? frameProcessEvts.map(e => e?.args?.data?.processId)
499
502
  // …But old traces and some timespan traces may not. In these situations, we'll assume the
500
503
  // primary process ID remains constant (as there were no navigations).
501
504
  : [mainFrameInfo.startingPid];
502
505
 
503
506
  const pidToTid = new Map();
504
507
 
505
- mainFramePids.forEach(pid => {
508
+ for (const pid of new Set(mainFramePids)) {
506
509
  // While renderer tids are generally predictable, we'll doublecheck it
507
510
  const threadNameEvt = keyEvents.find(e =>
508
511
  e.cat === '__metadata' &&
@@ -518,7 +521,7 @@ class TraceProcessor {
518
521
  }
519
522
 
520
523
  pidToTid.set(pid, tid);
521
- });
524
+ }
522
525
  return pidToTid;
523
526
  }
524
527
 
@@ -712,7 +715,8 @@ class TraceProcessor {
712
715
  }
713
716
  const frameEvents = keyEvents.filter(e => associatedToMainFrame(e));
714
717
 
715
- // Filter to just events matching the main frame ID or any child frame IDs.
718
+ // Filter to just events matching the main frame ID or any child frame IDs. The subframes
719
+ // are either in-process (same origin) or, potentially, out-of-process. (OOPIFs)
716
720
  let frameTreeEvents = [];
717
721
  if (frameIdToRootFrameId.has(mainFrameInfo.frameId)) {
718
722
  frameTreeEvents = keyEvents.filter(e => associatedToAllFrames(e));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "10.0.1-dev.20230227",
4
+ "version": "10.0.2",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -709,7 +709,7 @@ declare module Artifacts {
709
709
  timestamps: TraceTimes;
710
710
  /** The relative times from timeOrigin to key events, in milliseconds. */
711
711
  timings: TraceTimes;
712
- /** The subset of trace events from the page's process, sorted by timestamp. */
712
+ /** The subset of trace events from the main frame's process, sorted by timestamp. Due to cross-origin navigations, the main frame may have multiple processes, so events may be from more than one process. */
713
713
  processEvents: Array<TraceEvent>;
714
714
  /** The subset of trace events from the page's main thread, sorted by timestamp. */
715
715
  mainThreadEvents: Array<TraceEvent>;
@@ -977,6 +977,7 @@ export interface TraceEvent {
977
977
  processId?: number;
978
978
  isLoadingMainFrame?: boolean;
979
979
  documentLoaderURL?: string;
980
+ navigationId?: string;
980
981
  frames?: {
981
982
  frame: string;
982
983
  url: string;