lighthouse 9.5.0-dev.20230124 → 9.5.0-dev.20230125

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 (64) hide show
  1. package/core/audits/accessibility/accesskeys.js +1 -1
  2. package/core/audits/accessibility/aria-allowed-attr.js +1 -1
  3. package/core/audits/accessibility/aria-command-name.js +1 -1
  4. package/core/audits/accessibility/aria-hidden-body.js +1 -1
  5. package/core/audits/accessibility/aria-hidden-focus.js +1 -1
  6. package/core/audits/accessibility/aria-input-field-name.js +1 -1
  7. package/core/audits/accessibility/aria-meter-name.js +1 -1
  8. package/core/audits/accessibility/aria-progressbar-name.js +1 -1
  9. package/core/audits/accessibility/aria-required-attr.js +1 -1
  10. package/core/audits/accessibility/aria-required-children.js +1 -1
  11. package/core/audits/accessibility/aria-required-parent.js +1 -1
  12. package/core/audits/accessibility/aria-roles.js +1 -1
  13. package/core/audits/accessibility/aria-toggle-field-name.js +1 -1
  14. package/core/audits/accessibility/aria-tooltip-name.js +1 -1
  15. package/core/audits/accessibility/aria-treeitem-name.js +1 -1
  16. package/core/audits/accessibility/aria-valid-attr-value.js +1 -1
  17. package/core/audits/accessibility/aria-valid-attr.js +1 -1
  18. package/core/audits/accessibility/button-name.js +1 -1
  19. package/core/audits/accessibility/bypass.js +1 -1
  20. package/core/audits/accessibility/color-contrast.js +1 -1
  21. package/core/audits/accessibility/definition-list.js +1 -1
  22. package/core/audits/accessibility/dlitem.js +1 -1
  23. package/core/audits/accessibility/document-title.js +1 -1
  24. package/core/audits/accessibility/duplicate-id-active.js +1 -1
  25. package/core/audits/accessibility/duplicate-id-aria.js +1 -1
  26. package/core/audits/accessibility/form-field-multiple-labels.js +1 -1
  27. package/core/audits/accessibility/frame-title.js +1 -1
  28. package/core/audits/accessibility/heading-order.js +1 -1
  29. package/core/audits/accessibility/html-has-lang.js +1 -1
  30. package/core/audits/accessibility/html-lang-valid.js +1 -1
  31. package/core/audits/accessibility/image-alt.js +1 -1
  32. package/core/audits/accessibility/input-image-alt.js +1 -1
  33. package/core/audits/accessibility/label.js +1 -1
  34. package/core/audits/accessibility/link-name.js +1 -1
  35. package/core/audits/accessibility/list.js +1 -1
  36. package/core/audits/accessibility/listitem.js +1 -1
  37. package/core/audits/accessibility/meta-refresh.js +1 -1
  38. package/core/audits/accessibility/meta-viewport.js +1 -1
  39. package/core/audits/accessibility/object-alt.js +1 -1
  40. package/core/audits/accessibility/tabindex.js +1 -1
  41. package/core/audits/accessibility/td-headers-attr.js +1 -1
  42. package/core/audits/accessibility/th-has-data-cells.js +1 -1
  43. package/core/audits/accessibility/valid-lang.js +1 -1
  44. package/core/audits/accessibility/video-caption.js +1 -1
  45. package/core/audits/network-requests.js +7 -6
  46. package/core/computed/entity-classification.js +1 -1
  47. package/core/computed/metrics/responsiveness.js +5 -2
  48. package/core/computed/page-dependency-graph.js +1 -1
  49. package/core/gather/gatherers/accessibility.js +3 -1
  50. package/core/lib/network-request.d.ts +2 -0
  51. package/core/lib/network-request.js +3 -0
  52. package/core/lib/stack-packs.js +4 -0
  53. package/core/lib/tracehouse/trace-processor.d.ts +14 -5
  54. package/core/lib/tracehouse/trace-processor.js +85 -30
  55. package/core/lib/traces/metric-trace-events.js +1 -1
  56. package/package.json +4 -5
  57. package/shared/localization/locales/en-US.json +74 -44
  58. package/shared/localization/locales/en-XL.json +74 -44
  59. package/tsconfig.json +0 -2
  60. package/types/artifacts.d.ts +7 -2
  61. package/core/lib/minify-trace.d.ts +0 -6
  62. package/core/lib/minify-trace.js +0 -172
  63. package/core/util.cjs +0 -845
  64. package/core/util.d.cts +0 -342
@@ -125,6 +125,8 @@ class NetworkRequest {
125
125
  this.parsedURL = /** @type {ParsedURL} */ ({scheme: ''});
126
126
  this.documentURL = '';
127
127
 
128
+ /** When the renderer process initially discovers a network request, in milliseconds. */
129
+ this.rendererStartTime = -1;
128
130
  /**
129
131
  * When the network service is about to handle a request, ie. just before going to the
130
132
  * HTTP cache or going to the network for DNS/connection setup, in milliseconds.
@@ -222,6 +224,7 @@ class NetworkRequest {
222
224
  };
223
225
  this.isSecure = UrlUtils.isSecureScheme(this.parsedURL.scheme);
224
226
 
227
+ this.rendererStartTime = data.timestamp * 1000;
225
228
  // Expected to be overriden with better value in `_recomputeTimesWithResourceTiming`.
226
229
  this.startTime = data.timestamp * 1000;
227
230
 
@@ -19,6 +19,10 @@ const stackPacksToInclude = [
19
19
  packId: 'wordpress',
20
20
  requiredStacks: ['js:wordpress'],
21
21
  },
22
+ {
23
+ packId: 'wp-rocket',
24
+ requiredStacks: ['js:wp-rocket'],
25
+ },
22
26
  {
23
27
  packId: 'ezoic',
24
28
  requiredStacks: ['js:ezoic'],
@@ -148,13 +148,22 @@ export class TraceProcessor {
148
148
  static getMainThreadTopLevelEvents(trace: LH.Artifacts.ProcessedTrace, startTime?: number | undefined, endTime?: number | undefined): Array<ToplevelEvent>;
149
149
  /**
150
150
  * @param {LH.TraceEvent[]} events
151
- * @return {{pid: number, tid: number, frameId: string}}
151
+ * @return {{startingPid: number, frameId: string}}
152
152
  */
153
153
  static findMainFrameIds(events: LH.TraceEvent[]): {
154
- pid: number;
155
- tid: number;
154
+ startingPid: number;
156
155
  frameId: string;
157
156
  };
157
+ /**
158
+ * If there were any cross-origin navigations, there'll be more than one pid returned
159
+ * @param {{startingPid: number, frameId: string}} mainFrameInfo
160
+ * @param {LH.TraceEvent[]} keyEvents
161
+ * @return {Map<number, number>} Map where keys are process IDs and their values are thread IDs
162
+ */
163
+ static findMainFramePidTids(mainFrameInfo: {
164
+ startingPid: number;
165
+ frameId: string;
166
+ }, keyEvents: LH.TraceEvent[]): Map<number, number>;
158
167
  /**
159
168
  * @param {LH.TraceEvent} evt
160
169
  * @return {boolean}
@@ -239,14 +248,14 @@ export class TraceProcessor {
239
248
  * Can also be skewed by several hundred milliseconds or even seconds when the browser takes a long
240
249
  * time to unload `about:blank`.
241
250
  *
242
- * @param {{keyEvents: Array<LH.TraceEvent>, frameEvents: Array<LH.TraceEvent>, mainFrameIds: {frameId: string}}} traceEventSubsets
251
+ * @param {{keyEvents: Array<LH.TraceEvent>, frameEvents: Array<LH.TraceEvent>, mainFrameInfo: {frameId: string}}} traceEventSubsets
243
252
  * @param {TimeOriginDeterminationMethod} method
244
253
  * @return {LH.TraceEvent}
245
254
  */
246
255
  static computeTimeOrigin(traceEventSubsets: {
247
256
  keyEvents: Array<LH.TraceEvent>;
248
257
  frameEvents: Array<LH.TraceEvent>;
249
- mainFrameIds: {
258
+ mainFrameInfo: {
250
259
  frameId: string;
251
260
  };
252
261
  }, method: TimeOriginDeterminationMethod): LH.TraceEvent;
@@ -423,7 +423,7 @@ class TraceProcessor {
423
423
 
424
424
  /**
425
425
  * @param {LH.TraceEvent[]} events
426
- * @return {{pid: number, tid: number, frameId: string}}
426
+ * @return {{startingPid: number, frameId: string}}
427
427
  */
428
428
  static findMainFrameIds(events) {
429
429
  // Prefer the newer TracingStartedInBrowser event first, if it exists
@@ -433,14 +433,9 @@ class TraceProcessor {
433
433
  const frameId = mainFrame?.frame;
434
434
  const pid = mainFrame?.processId;
435
435
 
436
- const threadNameEvt = events.find(e => e.pid === pid && e.ph === 'M' &&
437
- e.cat === '__metadata' && e.name === 'thread_name' && e.args.name === 'CrRendererMain');
438
- const tid = threadNameEvt?.tid;
439
-
440
- if (pid && tid && frameId) {
436
+ if (pid && frameId) {
441
437
  return {
442
- pid,
443
- tid,
438
+ startingPid: pid,
444
439
  frameId,
445
440
  };
446
441
  }
@@ -454,8 +449,7 @@ class TraceProcessor {
454
449
  const frameId = startedInPageEvt.args.data.page;
455
450
  if (frameId) {
456
451
  return {
457
- pid: startedInPageEvt.pid,
458
- tid: startedInPageEvt.tid,
452
+ startingPid: startedInPageEvt.pid,
459
453
  frameId,
460
454
  };
461
455
  }
@@ -478,8 +472,7 @@ class TraceProcessor {
478
472
  const frameId = navStartEvt.args.frame;
479
473
  if (frameId) {
480
474
  return {
481
- pid: navStartEvt.pid,
482
- tid: navStartEvt.tid,
475
+ startingPid: navStartEvt.pid,
483
476
  frameId,
484
477
  };
485
478
  }
@@ -488,6 +481,47 @@ class TraceProcessor {
488
481
  throw this.createNoTracingStartedError();
489
482
  }
490
483
 
484
+ /**
485
+ * If there were any cross-origin navigations, there'll be more than one pid returned
486
+ * @param {{startingPid: number, frameId: string}} mainFrameInfo
487
+ * @param {LH.TraceEvent[]} keyEvents
488
+ * @return {Map<number, number>} Map where keys are process IDs and their values are thread IDs
489
+ */
490
+ static findMainFramePidTids(mainFrameInfo, keyEvents) {
491
+ const frameCommittedEvts = keyEvents.filter(evt =>
492
+ evt.name === 'FrameCommittedInBrowser' &&
493
+ evt.args?.data?.frame === mainFrameInfo.frameId
494
+ );
495
+
496
+ // "Modern" traces with a navigation have a FrameCommittedInBrowser event
497
+ const mainFramePids = frameCommittedEvts.length
498
+ ? frameCommittedEvts.map(e => e?.args?.data?.processId)
499
+ // …But old traces and some timespan traces may not. In these situations, we'll assume the
500
+ // primary process ID remains constant (as there were no navigations).
501
+ : [mainFrameInfo.startingPid];
502
+
503
+ const pidToTid = new Map();
504
+
505
+ mainFramePids.forEach(pid => {
506
+ // While renderer tids are generally predictable, we'll doublecheck it
507
+ const threadNameEvt = keyEvents.find(e =>
508
+ e.cat === '__metadata' &&
509
+ e.pid === pid &&
510
+ e.ph === 'M' &&
511
+ e.name === 'thread_name' &&
512
+ e.args.name === 'CrRendererMain'
513
+ );
514
+ const tid = threadNameEvt?.tid;
515
+
516
+ if (!tid) {
517
+ throw new Error('Unable to determine tid for renderer process');
518
+ }
519
+
520
+ pidToTid.set(pid, tid);
521
+ });
522
+ return pidToTid;
523
+ }
524
+
491
525
  /**
492
526
  * @param {LH.TraceEvent} evt
493
527
  * @return {boolean}
@@ -583,6 +617,9 @@ class TraceProcessor {
583
617
  while (parentFrames.has(cur)) {
584
618
  cur = /** @type {string} */ (parentFrames.get(cur));
585
619
  }
620
+ if (cur === undefined) {
621
+ throw new Error('Unexpected undefined frameId');
622
+ }
586
623
  frameIdToRootFrameId.set(frame.id, cur);
587
624
  }
588
625
 
@@ -609,7 +646,15 @@ class TraceProcessor {
609
646
  });
610
647
 
611
648
  // Find the inspected frame
612
- const mainFrameIds = this.findMainFrameIds(keyEvents);
649
+ const mainFrameInfo = this.findMainFrameIds(keyEvents);
650
+ const rendererPidToTid = this.findMainFramePidTids(mainFrameInfo, keyEvents);
651
+
652
+ // Subset all trace events to just our tab's process (incl threads other than main)
653
+ // stable-sort events to keep them correctly nested.
654
+ const processEvents = TraceProcessor
655
+ .filteredTraceSort(trace.traceEvents, e => rendererPidToTid.has(e.pid));
656
+
657
+ // TODO(paulirish): filter down frames (and subsequent actions) to the primary process tree & frame tree
613
658
 
614
659
  /** @type {Map<string, {id: string, url: string, parent?: string}>} */
615
660
  const framesById = new Map();
@@ -645,18 +690,32 @@ class TraceProcessor {
645
690
  parent: evt.args.data.parent,
646
691
  });
647
692
  });
693
+
648
694
  const frames = [...framesById.values()];
649
695
  const frameIdToRootFrameId = this.resolveRootFrames(frames);
650
696
 
697
+ const inspectedTreeFrameIds = [...frameIdToRootFrameId.entries()]
698
+ .filter(([, rootFrameId]) => rootFrameId === mainFrameInfo.frameId)
699
+ .map(([child]) => child);
700
+
651
701
  // Filter to just events matching the main frame ID, just to make sure.
652
- const frameEvents = keyEvents.filter(e => e.args.frame === mainFrameIds.frameId);
702
+ /** @param {LH.TraceEvent} e */
703
+ function associatedToMainFrame(e) {
704
+ const frameId = e.args?.data?.frame || e.args.frame;
705
+ return frameId === mainFrameInfo.frameId;
706
+ }
707
+
708
+ /** @param {LH.TraceEvent} e */
709
+ function associatedToAllFrames(e) {
710
+ const frameId = e.args?.data?.frame || e.args.frame;
711
+ return frameId ? inspectedTreeFrameIds.includes(frameId) : false;
712
+ }
713
+ const frameEvents = keyEvents.filter(e => associatedToMainFrame(e));
653
714
 
654
715
  // Filter to just events matching the main frame ID or any child frame IDs.
655
716
  let frameTreeEvents = [];
656
- if (frameIdToRootFrameId.has(mainFrameIds.frameId)) {
657
- frameTreeEvents = keyEvents.filter(e => {
658
- return e.args.frame && frameIdToRootFrameId.get(e.args.frame) === mainFrameIds.frameId;
659
- });
717
+ if (frameIdToRootFrameId.has(mainFrameInfo.frameId)) {
718
+ frameTreeEvents = keyEvents.filter(e => associatedToAllFrames(e));
660
719
  } else {
661
720
  // In practice, there should always be TracingStartedInBrowser/FrameCommittedInBrowser events to
662
721
  // define the frame tree. Unfortunately, many test traces do not that frame info due to minification.
@@ -665,23 +724,17 @@ class TraceProcessor {
665
724
  'TraceProcessor',
666
725
  'frameTreeEvents may be incomplete, make sure the trace has frame events'
667
726
  );
668
- frameIdToRootFrameId.set(mainFrameIds.frameId, mainFrameIds.frameId);
727
+ frameIdToRootFrameId.set(mainFrameInfo.frameId, mainFrameInfo.frameId);
669
728
  frameTreeEvents = frameEvents;
670
729
  }
671
730
 
672
731
  // Compute our time origin to use for all relative timings.
673
732
  const timeOriginEvt = this.computeTimeOrigin(
674
- {keyEvents, frameEvents, mainFrameIds},
733
+ {keyEvents, frameEvents, mainFrameInfo: mainFrameInfo},
675
734
  timeOriginDeterminationMethod
676
735
  );
677
736
 
678
- // Subset all trace events to just our tab's process (incl threads other than main)
679
- // stable-sort events to keep them correctly nested.
680
- const processEvents = TraceProcessor
681
- .filteredTraceSort(trace.traceEvents, e => e.pid === mainFrameIds.pid);
682
-
683
- const mainThreadEvents = processEvents
684
- .filter(e => e.tid === mainFrameIds.tid);
737
+ const mainThreadEvents = processEvents.filter(e => e.tid === rendererPidToTid.get(e.pid));
685
738
 
686
739
  // Ensure our traceEnd reflects all page activity.
687
740
  const traceEnd = this.computeTraceEnd(trace.traceEvents, timeOriginEvt);
@@ -694,7 +747,7 @@ class TraceProcessor {
694
747
  frameEvents,
695
748
  frameTreeEvents,
696
749
  processEvents,
697
- mainFrameIds,
750
+ mainFrameInfo,
698
751
  timeOriginEvt,
699
752
  timings: {
700
753
  timeOrigin: 0,
@@ -704,6 +757,8 @@ class TraceProcessor {
704
757
  timeOrigin: timeOriginEvt.ts,
705
758
  traceEnd: traceEnd.timestamp,
706
759
  },
760
+ _keyEvents: keyEvents,
761
+ _rendererPidToTid: rendererPidToTid,
707
762
  };
708
763
  }
709
764
 
@@ -807,7 +862,7 @@ class TraceProcessor {
807
862
  * Can also be skewed by several hundred milliseconds or even seconds when the browser takes a long
808
863
  * time to unload `about:blank`.
809
864
  *
810
- * @param {{keyEvents: Array<LH.TraceEvent>, frameEvents: Array<LH.TraceEvent>, mainFrameIds: {frameId: string}}} traceEventSubsets
865
+ * @param {{keyEvents: Array<LH.TraceEvent>, frameEvents: Array<LH.TraceEvent>, mainFrameInfo: {frameId: string}}} traceEventSubsets
811
866
  * @param {TimeOriginDeterminationMethod} method
812
867
  * @return {LH.TraceEvent}
813
868
  */
@@ -833,7 +888,7 @@ class TraceProcessor {
833
888
  const fetchStart = traceEventSubsets.keyEvents.find(event => {
834
889
  if (event.name !== 'ResourceSendRequest') return false;
835
890
  const data = event.args.data || {};
836
- return data.frame === traceEventSubsets.mainFrameIds.frameId;
891
+ return data.frame === traceEventSubsets.mainFrameInfo.frameId;
837
892
  });
838
893
  if (!fetchStart) throw this.createNoResourceSendRequestError();
839
894
  return fetchStart;
@@ -128,7 +128,7 @@ class MetricTraceEvents {
128
128
  if (!timeOriginMetric) return {errorMessage: 'timeorigin Metric not found in definitions'};
129
129
  try {
130
130
  const frameIds = TraceProcessor.findMainFrameIds(this._traceEvents);
131
- return {pid: frameIds.pid, tid: frameIds.tid, ts: timeOriginMetric.ts};
131
+ return {pid: frameIds.startingPid, tid: 1, ts: timeOriginMetric.ts};
132
132
  } catch (err) {
133
133
  return {errorMessage: err.message};
134
134
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "9.5.0-dev.20230124",
4
+ "version": "9.5.0-dev.20230125",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -86,7 +86,6 @@
86
86
  "diff:sample-json": "yarn i18n:checks && bash core/scripts/assert-golden-lhr-unchanged.sh",
87
87
  "diff:flow-sample-json": "yarn i18n:collect-strings && bash core/scripts/assert-baseline-flow-result-unchanged.sh",
88
88
  "computeBenchmarkIndex": "./core/scripts/benchmark.js",
89
- "minify-latest-run": "./core/scripts/lantern/minify-trace.js ./latest-run/defaultPass.trace.json ./latest-run/defaultPass.trace.min.json && ./core/scripts/lantern/minify-devtoolslog.js ./latest-run/defaultPass.devtoolslog.json ./latest-run/defaultPass.devtoolslog.min.json",
90
89
  "save-latest-run": "./core/scripts/save-latest-run.sh",
91
90
  "compile-proto": "protoc --python_out=./ ./proto/lighthouse-result.proto && mv ./proto/*_pb2.py ./proto/scripts || (echo \"❌ Install protobuf = 3.20.x to compile the proto file.\" && false)",
92
91
  "build-proto-roundtrip": "mkdir -p .tmp && python3 proto/scripts/json_roundtrip_via_proto.py",
@@ -187,7 +186,7 @@
187
186
  },
188
187
  "dependencies": {
189
188
  "@sentry/node": "^6.17.4",
190
- "axe-core": "4.4.1",
189
+ "axe-core": "4.6.3",
191
190
  "chrome-launcher": "^0.15.1",
192
191
  "configstore": "^5.0.1",
193
192
  "csp_evaluator": "1.1.1",
@@ -195,9 +194,9 @@
195
194
  "http-link-header": "^0.8.0",
196
195
  "intl-messageformat": "^4.4.0",
197
196
  "jpeg-js": "^0.4.4",
198
- "js-library-detector": "^6.5.0",
197
+ "js-library-detector": "^6.6.0",
199
198
  "lighthouse-logger": "^1.3.0",
200
- "lighthouse-stack-packs": "1.8.2",
199
+ "lighthouse-stack-packs": "1.9.0",
201
200
  "lodash": "^4.17.21",
202
201
  "lookup-closest-locale": "6.2.0",
203
202
  "metaviewport-parser": "0.3.0",