lighthouse 10.0.1 → 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
 
@@ -74,6 +74,8 @@ class BFCache extends Audit {
74
74
  // TODO: Analyze more than one bf cache failure.
75
75
  const {notRestoredReasonsTree} = failures[0];
76
76
 
77
+ let totalIssues = 0;
78
+
77
79
  /** @type {LH.Audit.Details.TableItem[]} */
78
80
  const results = [];
79
81
 
@@ -81,6 +83,8 @@ class BFCache extends Audit {
81
83
  const reasonsMap = notRestoredReasonsTree[failureType];
82
84
 
83
85
  for (const [reason, frameUrls] of Object.entries(reasonsMap)) {
86
+ totalIssues += frameUrls.length;
87
+
84
88
  results.push({
85
89
  reason: NotRestoredReasonDescription[reason]?.name ?? reason,
86
90
  failureType: FAILURE_TYPE_TO_STRING[failureType],
@@ -104,8 +108,8 @@ class BFCache extends Audit {
104
108
 
105
109
  const details = Audit.makeTableDetails(headings, results);
106
110
 
107
- const displayValue = results.length ?
108
- str_(UIStrings.displayValue, {itemCount: results.length}) :
111
+ const displayValue = totalIssues ?
112
+ str_(UIStrings.displayValue, {itemCount: totalIssues}) :
109
113
  undefined;
110
114
 
111
115
  return {
@@ -1,59 +1,54 @@
1
1
  {
2
- "moduleSizes": [498, 155, 242, 615, 220, 657, 651, 1664, 790, 1534, 558, 279, 868, 974, 618, 356, 720, 133, 826, 732, 235, 552, 170, 585, 1030, 210, 349, 179, 546, 167, 1634, 118, 199, 478, 849, 470, 452, 417, 147, 60, 180, 433, 360, 303, 1325, 1518, 397, 201, 550, 226, 132, 156, 198, 312, 544, 2125, 658, 778, 1084, 701, 401, 81, 716, 632, 321, 428, 648, 804, 718, 130, 1443, 142, 374, 259, 286, 403, 821, 938, 514, 654, 280, 328, 186, 233, 243, 553, 267, 187, 206, 879, 105, 343, 779, 833, 773, 275, 477, 696, 224, 759, 671, 772, 746, 716, 182, 304, 658, 473, 592, 235, 334, 277, 404, 420, 280, 675, 1034, 508, 725, 526, 498, 498, 499, 752, 661, 276, 275, 843, 1698, 962, 562, 609, 573, 1048, 205, 374, 226, 625, 632, 308, 772, 641, 233],
2
+ "moduleSizes": [498, 265, 277, 263, 453, 219, 216, 546, 339, 1608, 671, 1525, 420, 214, 504, 98, 524, 196, 268, 642, 204, 742, 618, 169, 394, 127, 433, 1473, 779, 239, 144, 182, 254, 77, 508, 124, 1388, 75, 133, 301, 362, 170, 1078, 182, 490, 195, 321, 316, 447, 551, 216, 284, 253, 17, 107, 295, 356, 345, 1939, 1596, 291, 139, 259, 1291, 179, 528, 174, 61, 326, 20, 444, 522, 104, 1945, 120, 1943, 680, 1409, 850, 630, 288, 38, 695, 569, 106, 587, 208, 370, 606, 766, 535, 616, 200, 170, 224, 422, 970, 978, 498, 284, 241, 210, 151, 194, 178, 814, 205, 189, 215, 111, 236, 147, 237, 191, 691, 212, 432, 499, 445, 176, 333, 129, 414, 617, 380, 251, 199, 524, 515, 681, 160, 259, 295, 283, 178, 472, 786, 520, 202, 575, 575, 349, 549, 458, 166, 173, 508, 1522, 743, 414, 431, 393, 899, 137, 270, 131, 472, 457, 205, 778, 801, 133],
3
3
  "dependencies": {
4
- "Array.prototype.fill": [3, 5, 8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 40, 42, 43, 45, 48, 51, 52, 53, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 91],
5
- "Array.prototype.filter": [1, 8, 9, 10, 12, 14, 17, 19, 21, 22, 27, 28, 29, 30, 33, 35, 38, 39, 42, 43, 45, 47, 48, 51, 52, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 92],
6
- "Array.prototype.find": [1, 3, 8, 9, 12, 14, 17, 19, 21, 22, 29, 30, 33, 35, 38, 39, 40, 42, 43, 45, 47, 48, 51, 52, 53, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 94],
7
- "Array.prototype.findIndex": [1, 3, 8, 9, 12, 14, 17, 19, 21, 22, 29, 30, 33, 35, 38, 39, 40, 42, 43, 45, 47, 48, 51, 52, 53, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 93],
8
- "Array.prototype.forEach": [1, 6, 8, 9, 11, 12, 14, 17, 19, 21, 22, 29, 30, 33, 35, 38, 39, 42, 43, 45, 47, 48, 51, 52, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 95],
9
- "Array.from": [1, 7, 8, 15, 16, 17, 18, 19, 21, 22, 23, 29, 30, 33, 35, 36, 38, 39, 42, 43, 45, 46, 48, 51, 52, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 86, 87, 88, 89, 96],
10
- "Array.isArray": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 47, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 98],
11
- "Array.prototype.map": [1, 8, 9, 10, 12, 14, 17, 19, 21, 22, 27, 28, 29, 30, 33, 35, 38, 39, 42, 43, 45, 47, 48, 51, 52, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 99],
12
- "Array.of": [8, 17, 19, 21, 22, 23, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 100],
13
- "Array.prototype.reduce": [1, 8, 11, 12, 13, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 102],
14
- "Array.prototype.reduceRight": [1, 8, 11, 12, 13, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 101],
15
- "Array.prototype.some": [1, 8, 9, 11, 12, 14, 17, 19, 21, 22, 29, 30, 33, 35, 38, 39, 42, 43, 45, 47, 48, 51, 52, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 88, 89, 103],
16
- "Date.now": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 104],
17
- "Date.prototype.toISOString": [8, 17, 19, 21, 22, 24, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 80, 81, 82, 83, 87, 105],
18
- "Date.prototype.toJSON": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 106],
19
- "Date.prototype.toString": [21, 22, 38, 39, 43, 45, 51, 53, 70, 72, 73, 74, 75, 87, 107],
20
- "Function.prototype.name": [108],
21
- "Number.isInteger": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 49, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 109],
22
- "Number.isSafeInteger": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 49, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 110],
23
- "Number.parseInt": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 54, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 79, 80, 81, 82, 83, 87, 90, 111],
24
- "Object.defineProperties": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 112],
25
- "Object.defineProperty": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 113],
26
- "Object.freeze": [8, 17, 19, 21, 22, 29, 30, 32, 35, 38, 39, 42, 43, 44, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 115],
27
- "Object.getOwnPropertyNames": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 59, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 117],
28
- "Object.getPrototypeOf": [8, 17, 19, 20, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 62, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 118],
29
- "Object.isExtensible": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 119],
30
- "Object.isFrozen": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 120],
31
- "Object.isSealed": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 121],
32
- "Object.keys": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 122],
33
- "Object.preventExtensions": [8, 17, 19, 21, 22, 29, 30, 32, 35, 38, 39, 42, 43, 44, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 123],
34
- "Object.seal": [8, 17, 19, 21, 22, 29, 30, 32, 35, 38, 39, 42, 43, 44, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 124],
35
- "Object.setPrototypeOf": [2, 8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 125],
36
- "Reflect.apply": [1, 8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 127],
37
- "Reflect.construct": [1, 8, 17, 19, 21, 22, 29, 30, 34, 35, 38, 39, 40, 42, 43, 45, 48, 51, 53, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 128],
38
- "Reflect.defineProperty": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 129],
39
- "Reflect.deleteProperty": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 130],
40
- "Reflect.get": [8, 17, 19, 20, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 62, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 133],
41
- "Reflect.getOwnPropertyDescriptor": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 131],
42
- "Reflect.getPrototypeOf": [8, 17, 19, 20, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 62, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 87, 132],
43
- "Reflect.has": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 134],
44
- "Reflect.isExtensible": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 135],
45
- "Reflect.ownKeys": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 136],
46
- "Reflect.preventExtensions": [8, 17, 19, 21, 22, 29, 30, 32, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 137],
47
- "Reflect.setPrototypeOf": [2, 8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 66, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 138],
48
- "String.prototype.codePointAt": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 76, 80, 81, 82, 83, 87, 139],
49
- "String.fromCodePoint": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 140],
50
- "String.raw": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 141],
51
- "String.prototype.repeat": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 78, 80, 81, 82, 83, 87, 142],
52
- "Array.prototype.includes": [3, 8, 12, 17, 19, 21, 22, 29, 30, 35, 38, 39, 40, 42, 43, 45, 48, 51, 52, 53, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 88, 89, 97],
53
- "Object.entries": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 114],
54
- "Object.getOwnPropertyDescriptors": [8, 17, 19, 21, 22, 23, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 65, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 116],
55
- "Object.values": [8, 17, 19, 21, 22, 29, 30, 35, 38, 39, 42, 43, 45, 48, 51, 53, 58, 60, 61, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 87, 126]
4
+ "Array.prototype.fill": [4, 7, 10, 20, 22, 24, 25, 28, 35, 36, 53, 54, 56, 57, 59, 65, 72, 73, 74, 75, 76, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 113, 115],
5
+ "Array.prototype.filter": [10, 11, 12, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 56, 57, 59, 61, 63, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 116],
6
+ "Array.prototype.find": [4, 10, 11, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 54, 56, 57, 59, 61, 63, 65, 72, 73, 74, 75, 76, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 107, 113, 118],
7
+ "Array.prototype.findIndex": [4, 10, 11, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 54, 56, 57, 59, 61, 63, 65, 72, 73, 74, 75, 76, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 107, 113, 117],
8
+ "Array.prototype.forEach": [8, 10, 11, 13, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 56, 57, 59, 61, 63, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 119],
9
+ "Array.from": [9, 10, 18, 19, 20, 21, 22, 24, 25, 26, 28, 35, 36, 40, 45, 48, 49, 53, 56, 57, 59, 60, 63, 65, 71, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 120],
10
+ "Array.isArray": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 61, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 121],
11
+ "Array.prototype.map": [10, 11, 12, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 56, 57, 59, 61, 63, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 122],
12
+ "Array.of": [10, 20, 21, 22, 24, 25, 26, 28, 35, 36, 53, 56, 57, 59, 63, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 123],
13
+ "Array.prototype.some": [10, 11, 13, 16, 17, 20, 21, 22, 24, 25, 28, 35, 36, 40, 45, 53, 56, 57, 59, 61, 63, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 113, 124],
14
+ "Date.now": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 125],
15
+ "Date.prototype.toISOString": [10, 20, 21, 22, 24, 25, 27, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 97, 98, 100, 101, 102, 103, 107, 108, 113, 126],
16
+ "Date.prototype.toJSON": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 127],
17
+ "Date.prototype.toString": [24, 25, 28, 53, 57, 59, 73, 93, 113, 128],
18
+ "Function.prototype.name": [129],
19
+ "Number.isInteger": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 66, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 130],
20
+ "Number.isSafeInteger": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 66, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 131],
21
+ "Object.defineProperties": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 76, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 113, 132],
22
+ "Object.defineProperty": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 133],
23
+ "Object.freeze": [6, 10, 14, 20, 22, 24, 25, 26, 28, 35, 36, 38, 53, 56, 57, 58, 59, 65, 72, 73, 74, 78, 79, 80, 81, 83, 85, 87, 91, 93, 100, 101, 102, 103, 113, 135],
24
+ "Object.getPrototypeOf": [10, 20, 22, 23, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 82, 85, 87, 91, 93, 100, 101, 102, 103, 113, 137],
25
+ "Object.isExtensible": [6, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 83, 85, 87, 91, 93, 100, 101, 102, 103, 113, 138],
26
+ "Object.isFrozen": [6, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 139],
27
+ "Object.isSealed": [6, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 140],
28
+ "Object.keys": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 113, 141],
29
+ "Object.preventExtensions": [6, 10, 14, 20, 22, 24, 25, 26, 28, 35, 36, 38, 53, 56, 57, 58, 59, 65, 72, 73, 74, 78, 79, 80, 81, 83, 85, 87, 91, 93, 100, 101, 102, 103, 113, 142],
30
+ "Object.seal": [6, 10, 14, 20, 22, 24, 25, 26, 28, 35, 36, 38, 53, 56, 57, 58, 59, 65, 72, 73, 74, 78, 79, 80, 81, 83, 85, 87, 91, 93, 100, 101, 102, 103, 113, 143],
31
+ "Object.setPrototypeOf": [3, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 88, 91, 93, 100, 101, 102, 103, 113, 144],
32
+ "Reflect.apply": [10, 20, 22, 24, 25, 28, 35, 36, 39, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 146],
33
+ "Reflect.construct": [2, 10, 15, 20, 21, 22, 24, 25, 28, 35, 36, 39, 42, 53, 54, 56, 57, 59, 63, 65, 72, 73, 74, 75, 76, 78, 80, 81, 85, 86, 87, 91, 93, 100, 101, 102, 103, 107, 113, 147],
34
+ "Reflect.defineProperty": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 148],
35
+ "Reflect.deleteProperty": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 149],
36
+ "Reflect.get": [10, 20, 22, 23, 24, 25, 28, 35, 36, 53, 56, 57, 59, 64, 65, 72, 73, 74, 78, 80, 81, 82, 85, 87, 91, 93, 100, 101, 102, 103, 113, 152],
37
+ "Reflect.getOwnPropertyDescriptor": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 150],
38
+ "Reflect.getPrototypeOf": [10, 20, 22, 23, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 82, 85, 87, 91, 93, 100, 101, 102, 103, 113, 151],
39
+ "Reflect.has": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 153],
40
+ "Reflect.isExtensible": [6, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 83, 85, 87, 91, 93, 100, 101, 102, 103, 113, 154],
41
+ "Reflect.ownKeys": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 155],
42
+ "Reflect.preventExtensions": [10, 20, 22, 24, 25, 28, 35, 36, 38, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 156],
43
+ "Reflect.setPrototypeOf": [3, 10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 88, 91, 93, 100, 101, 102, 103, 113, 157],
44
+ "String.prototype.codePointAt": [10, 20, 21, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 96, 100, 101, 102, 103, 107, 108, 113, 158],
45
+ "String.fromCodePoint": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 159],
46
+ "String.raw": [10, 20, 21, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 107, 108, 113, 160],
47
+ "String.prototype.repeat": [10, 20, 21, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 98, 100, 101, 102, 103, 107, 108, 113, 161],
48
+ "Object.entries": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 86, 87, 89, 91, 93, 100, 101, 102, 103, 113, 134],
49
+ "Object.getOwnPropertyDescriptors": [10, 20, 22, 24, 25, 26, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 87, 91, 93, 100, 101, 102, 103, 113, 136],
50
+ "Object.values": [10, 20, 22, 24, 25, 28, 35, 36, 53, 56, 57, 59, 65, 72, 73, 74, 78, 80, 81, 85, 86, 87, 89, 91, 93, 100, 101, 102, 103, 113, 145]
56
51
  },
57
- "maxSize": 77759,
58
- "baseSize": 3708
59
- }
52
+ "maxSize": 72786,
53
+ "baseSize": 11897
54
+ }
@@ -1,48 +1,57 @@
1
1
  export default PrioritizeLcpImage;
2
+ export type InitiatorType = LH.Crdp.Network.Initiator['type'] | 'redirect' | 'fallbackToMain';
2
3
  export type InitiatorPath = Array<{
3
4
  url: string;
4
- initiatorType: string;
5
+ initiatorType: InitiatorType;
5
6
  }>;
6
7
  /**
7
- * @typedef {Array<{url: string, initiatorType: string}>} InitiatorPath
8
+ * @typedef {LH.Crdp.Network.Initiator['type']|'redirect'|'fallbackToMain'} InitiatorType
9
+ * @typedef {Array<{url: string, initiatorType: InitiatorType}>} InitiatorPath
8
10
  */
9
11
  declare class PrioritizeLcpImage extends Audit {
10
12
  /**
11
13
  *
12
14
  * @param {LH.Artifacts.NetworkRequest} request
13
15
  * @param {LH.Artifacts.NetworkRequest} mainResource
14
- * @param {Array<LH.Gatherer.Simulation.GraphNode>} initiatorPath
16
+ * @param {InitiatorPath} initiatorPath
15
17
  * @return {boolean}
16
18
  */
17
- static shouldPreloadRequest(request: LH.Artifacts.NetworkRequest, mainResource: LH.Artifacts.NetworkRequest, initiatorPath: Array<LH.Gatherer.Simulation.GraphNode>): boolean;
19
+ static shouldPreloadRequest(request: LH.Artifacts.NetworkRequest, mainResource: LH.Artifacts.NetworkRequest, initiatorPath: InitiatorPath): boolean;
18
20
  /**
19
21
  * @param {LH.Gatherer.Simulation.GraphNode} graph
20
- * @param {string} imageUrl
21
- * @return {{lcpNode: LH.Gatherer.Simulation.GraphNetworkNode|undefined, path: Array<LH.Gatherer.Simulation.GraphNetworkNode>|undefined}}
22
+ * @param {NetworkRequest} lcpRecord
23
+ * @return {LH.Gatherer.Simulation.GraphNetworkNode|undefined}
22
24
  */
23
- static findLCPNode(graph: LH.Gatherer.Simulation.GraphNode, imageUrl: string): {
24
- lcpNode: LH.Gatherer.Simulation.GraphNetworkNode | undefined;
25
- path: Array<LH.Gatherer.Simulation.GraphNetworkNode> | undefined;
26
- };
25
+ static findLCPNode(graph: LH.Gatherer.Simulation.GraphNode, lcpRecord: NetworkRequest): LH.Gatherer.Simulation.GraphNetworkNode | undefined;
26
+ /**
27
+ * Get the initiator path starting with lcpRecord back to mainResource, inclusive.
28
+ * Navigation redirects *to* the mainResource are not included.
29
+ * Path returned will always be at least [lcpRecord, mainResource].
30
+ * @param {NetworkRequest} lcpRecord
31
+ * @param {NetworkRequest} mainResource
32
+ * @return {InitiatorPath}
33
+ */
34
+ static getLcpInitiatorPath(lcpRecord: NetworkRequest, mainResource: NetworkRequest): InitiatorPath;
27
35
  /**
28
36
  * @param {LH.Artifacts.NetworkRequest} mainResource
29
37
  * @param {LH.Gatherer.Simulation.GraphNode} graph
30
- * @param {string | undefined} lcpUrl
38
+ * @param {NetworkRequest|undefined} lcpRecord
31
39
  * @return {{lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode, initiatorPath?: InitiatorPath}}
32
40
  */
33
- static getLCPNodeToPreload(mainResource: LH.Artifacts.NetworkRequest, graph: LH.Gatherer.Simulation.GraphNode, lcpUrl: string | undefined): {
41
+ static getLCPNodeToPreload(mainResource: LH.Artifacts.NetworkRequest, graph: LH.Gatherer.Simulation.GraphNode, lcpRecord: NetworkRequest | undefined): {
34
42
  lcpNodeToPreload?: import("../lib/dependency-graph/network-node.js").NetworkNode | undefined;
35
43
  initiatorPath?: InitiatorPath | undefined;
36
44
  };
37
45
  /**
38
- * Match the LCP event with the paint event to get the URL of the image actually painted.
46
+ * Match the LCP event with the paint event to get the request of the image actually painted.
39
47
  * This could differ from the `ImageElement` associated with the nodeId if e.g. the LCP
40
48
  * was a pseudo-element associated with a node containing a smaller background-image.
41
49
  * @param {LH.Trace} trace
42
50
  * @param {LH.Artifacts.ProcessedNavigation} processedNavigation
43
- * @return {string | undefined}
51
+ * @param {Array<NetworkRequest>} networkRecords
52
+ * @return {NetworkRequest|undefined}
44
53
  */
45
- static getLcpUrl(trace: LH.Trace, processedNavigation: LH.Artifacts.ProcessedNavigation): string | undefined;
54
+ static getLcpRecord(trace: LH.Trace, processedNavigation: LH.Artifacts.ProcessedNavigation, networkRecords: Array<NetworkRequest>): NetworkRequest | undefined;
46
55
  /**
47
56
  * Computes the estimated effect of preloading the LCP image.
48
57
  * @param {LH.Artifacts.TraceElement} lcpElement
@@ -12,6 +12,7 @@ import {LanternLargestContentfulPaint} from '../computed/metrics/lantern-largest
12
12
  import {LoadSimulator} from '../computed/load-simulator.js';
13
13
  import {ByteEfficiencyAudit} from './byte-efficiency/byte-efficiency-audit.js';
14
14
  import {ProcessedNavigation} from '../computed/processed-navigation.js';
15
+ import {NetworkRecords} from '../computed/network-records.js';
15
16
 
16
17
  const UIStrings = {
17
18
  /** Title of a lighthouse audit that tells a user to preload an image in order to improve their LCP time. */
@@ -24,7 +25,8 @@ const UIStrings = {
24
25
  const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings);
25
26
 
26
27
  /**
27
- * @typedef {Array<{url: string, initiatorType: string}>} InitiatorPath
28
+ * @typedef {LH.Crdp.Network.Initiator['type']|'redirect'|'fallbackToMain'} InitiatorType
29
+ * @typedef {Array<{url: string, initiatorType: InitiatorType}>} InitiatorPath
28
30
  */
29
31
 
30
32
  class PrioritizeLcpImage extends Audit {
@@ -46,64 +48,92 @@ class PrioritizeLcpImage extends Audit {
46
48
  *
47
49
  * @param {LH.Artifacts.NetworkRequest} request
48
50
  * @param {LH.Artifacts.NetworkRequest} mainResource
49
- * @param {Array<LH.Gatherer.Simulation.GraphNode>} initiatorPath
51
+ * @param {InitiatorPath} initiatorPath
50
52
  * @return {boolean}
51
53
  */
52
54
  static shouldPreloadRequest(request, mainResource, initiatorPath) {
53
- const mainResourceDepth = mainResource.redirects ? mainResource.redirects.length : 0;
54
-
55
55
  // If it's already preloaded, no need to recommend it.
56
56
  if (request.isLinkPreload) return false;
57
57
  // It's not a request loaded over the network, don't recommend it.
58
58
  if (NetworkRequest.isNonNetworkRequest(request)) return false;
59
- // It's already discoverable from the main document, don't recommend it.
60
- if (initiatorPath.length <= mainResourceDepth) return false;
59
+ // It's already discoverable from the main document (a path of [lcpRecord, mainResource]), don't recommend it.
60
+ if (initiatorPath.length <= 2) return false;
61
61
  // Finally, return whether or not it belongs to the main frame
62
62
  return request.frameId === mainResource.frameId;
63
63
  }
64
64
 
65
65
  /**
66
66
  * @param {LH.Gatherer.Simulation.GraphNode} graph
67
- * @param {string} imageUrl
68
- * @return {{lcpNode: LH.Gatherer.Simulation.GraphNetworkNode|undefined, path: Array<LH.Gatherer.Simulation.GraphNetworkNode>|undefined}}
67
+ * @param {NetworkRequest} lcpRecord
68
+ * @return {LH.Gatherer.Simulation.GraphNetworkNode|undefined}
69
69
  */
70
- static findLCPNode(graph, imageUrl) {
71
- let lcpNode;
72
- let path;
73
- graph.traverse((node, traversalPath) => {
74
- if (node.type !== 'network') return;
75
- if (node.record.url === imageUrl) {
76
- lcpNode = node;
77
- path =
78
- traversalPath.slice(1).filter(initiator => initiator.type === 'network');
70
+ static findLCPNode(graph, lcpRecord) {
71
+ for (const {node} of graph.traverseGenerator()) {
72
+ if (node.type !== 'network') continue;
73
+ if (node.record.requestId === lcpRecord.requestId) {
74
+ return node;
79
75
  }
80
- });
81
- return {
82
- lcpNode,
83
- path,
84
- };
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Get the initiator path starting with lcpRecord back to mainResource, inclusive.
81
+ * Navigation redirects *to* the mainResource are not included.
82
+ * Path returned will always be at least [lcpRecord, mainResource].
83
+ * @param {NetworkRequest} lcpRecord
84
+ * @param {NetworkRequest} mainResource
85
+ * @return {InitiatorPath}
86
+ */
87
+ static getLcpInitiatorPath(lcpRecord, mainResource) {
88
+ /** @type {InitiatorPath} */
89
+ const initiatorPath = [];
90
+ let mainResourceReached = false;
91
+ /** @type {NetworkRequest|undefined} */
92
+ let request = lcpRecord;
93
+
94
+ while (request) {
95
+ mainResourceReached ||= request.requestId === mainResource.requestId;
96
+
97
+ /** @type {InitiatorType} */
98
+ let initiatorType = request.initiator?.type ?? 'other';
99
+ // Initiator type usually comes from redirect, but 'redirect' is used for more informative debugData.
100
+ if (request.initiatorRequest && request.initiatorRequest === request.redirectSource) {
101
+ initiatorType = 'redirect';
102
+ }
103
+ // Sometimes the initiator chain is broken and the best that can be done is stitch
104
+ // back to the main resource. Note this in the initiatorType.
105
+ if (!request.initiatorRequest && !mainResourceReached) {
106
+ initiatorType = 'fallbackToMain';
107
+ }
108
+
109
+ initiatorPath.push({url: request.url, initiatorType});
110
+
111
+ // Can't preload before the main resource, so break off initiator path there.
112
+ if (mainResourceReached) break;
113
+
114
+ // Continue up chain, falling back to mainResource if chain is broken.
115
+ request = request.initiatorRequest || mainResource;
116
+ }
117
+
118
+ return initiatorPath;
85
119
  }
86
120
 
87
121
  /**
88
122
  * @param {LH.Artifacts.NetworkRequest} mainResource
89
123
  * @param {LH.Gatherer.Simulation.GraphNode} graph
90
- * @param {string | undefined} lcpUrl
124
+ * @param {NetworkRequest|undefined} lcpRecord
91
125
  * @return {{lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode, initiatorPath?: InitiatorPath}}
92
126
  */
93
- static getLCPNodeToPreload(mainResource, graph, lcpUrl) {
94
- if (!lcpUrl) return {};
95
- const {lcpNode, path} = PrioritizeLcpImage.findLCPNode(graph, lcpUrl);
96
- if (!lcpNode || !path) return {};
127
+ static getLCPNodeToPreload(mainResource, graph, lcpRecord) {
128
+ if (!lcpRecord) return {};
129
+ const lcpNode = PrioritizeLcpImage.findLCPNode(graph, lcpRecord);
130
+ const initiatorPath = PrioritizeLcpImage.getLcpInitiatorPath(lcpRecord, mainResource);
131
+ if (!lcpNode) return {initiatorPath};
97
132
 
98
133
  // eslint-disable-next-line max-len
99
- const shouldPreload = PrioritizeLcpImage.shouldPreloadRequest(lcpNode.record, mainResource, path);
134
+ const shouldPreload = PrioritizeLcpImage.shouldPreloadRequest(lcpRecord, mainResource, initiatorPath);
100
135
  const lcpNodeToPreload = shouldPreload ? lcpNode : undefined;
101
136
 
102
- const initiatorPath = [
103
- {url: lcpNode.record.url, initiatorType: lcpNode.initiatorType},
104
- ...path.map(n => ({url: n.record.url, initiatorType: n.initiatorType})),
105
- ];
106
-
107
137
  return {
108
138
  lcpNodeToPreload,
109
139
  initiatorPath,
@@ -111,14 +141,15 @@ class PrioritizeLcpImage extends Audit {
111
141
  }
112
142
 
113
143
  /**
114
- * Match the LCP event with the paint event to get the URL of the image actually painted.
144
+ * Match the LCP event with the paint event to get the request of the image actually painted.
115
145
  * This could differ from the `ImageElement` associated with the nodeId if e.g. the LCP
116
146
  * was a pseudo-element associated with a node containing a smaller background-image.
117
147
  * @param {LH.Trace} trace
118
148
  * @param {LH.Artifacts.ProcessedNavigation} processedNavigation
119
- * @return {string | undefined}
149
+ * @param {Array<NetworkRequest>} networkRecords
150
+ * @return {NetworkRequest|undefined}
120
151
  */
121
- static getLcpUrl(trace, processedNavigation) {
152
+ static getLcpRecord(trace, processedNavigation, networkRecords) {
122
153
  // Use main-frame-only LCP to match the metric value.
123
154
  const lcpEvent = processedNavigation.largestContentfulPaintEvt;
124
155
  if (!lcpEvent) return;
@@ -131,7 +162,31 @@ class PrioritizeLcpImage extends Audit {
131
162
  // Get last candidate, in case there was more than one.
132
163
  }).sort((a, b) => b.ts - a.ts)[0];
133
164
 
134
- return lcpImagePaintEvent?.args.data?.imageUrl;
165
+ const lcpUrl = lcpImagePaintEvent?.args.data?.imageUrl;
166
+ if (!lcpUrl) return;
167
+
168
+ const candidates = networkRecords.filter(record => {
169
+ return record.url === lcpUrl &&
170
+ record.finished &&
171
+ // Same frame as LCP trace event.
172
+ record.frameId === lcpImagePaintEvent.args.frame &&
173
+ record.networkRequestTime < (processedNavigation.timestamps.largestContentfulPaint || 0);
174
+ }).map(record => {
175
+ // Follow any redirects to find the real image request.
176
+ while (record.redirectDestination) {
177
+ record = record.redirectDestination;
178
+ }
179
+ return record;
180
+ }).filter(record => {
181
+ // Don't select if also loaded by some other means (xhr, etc). `resourceType`
182
+ // isn't set on redirect _sources_, so have to check after following redirects.
183
+ return record.resourceType === 'Image';
184
+ });
185
+
186
+ // If there are still multiple candidates, at this point it appears the page
187
+ // simply made multiple requests for the image. The first loaded is the best
188
+ // guess of the request that made the image available for use.
189
+ return candidates.sort((a, b) => a.networkEndTime - b.networkEndTime)[0];
135
190
  }
136
191
 
137
192
  /**
@@ -233,7 +288,8 @@ class PrioritizeLcpImage extends Audit {
233
288
  const trace = artifacts.traces[PrioritizeLcpImage.DEFAULT_PASS];
234
289
  const devtoolsLog = artifacts.devtoolsLogs[PrioritizeLcpImage.DEFAULT_PASS];
235
290
  const URL = artifacts.URL;
236
- const metricData = {trace, devtoolsLog, gatherContext, settings: context.settings, URL};
291
+ const settings = context.settings;
292
+ const metricData = {trace, devtoolsLog, gatherContext, settings, URL};
237
293
  const lcpElement = artifacts.TraceElements
238
294
  .find(element => element.traceEventType === 'largest-contentful-paint');
239
295
 
@@ -241,17 +297,17 @@ class PrioritizeLcpImage extends Audit {
241
297
  return {score: null, notApplicable: true};
242
298
  }
243
299
 
244
- const [processedNavigation, mainResource, lanternLCP, simulator] = await Promise.all([
245
- ProcessedNavigation.request(trace, context),
246
- MainResource.request({devtoolsLog, URL}, context),
247
- LanternLargestContentfulPaint.request(metricData, context),
248
- LoadSimulator.request({devtoolsLog, settings: context.settings}, context),
249
- ]);
300
+ const networkRecords = await NetworkRecords.request(devtoolsLog, context);
301
+ const processedNavigation = await ProcessedNavigation.request(trace, context);
302
+ const mainResource = await MainResource.request({devtoolsLog, URL}, context);
303
+ const lanternLCP = await LanternLargestContentfulPaint.request(metricData, context);
304
+ const simulator = await LoadSimulator.request({devtoolsLog, settings}, context);
250
305
 
251
- const lcpUrl = PrioritizeLcpImage.getLcpUrl(trace, processedNavigation);
306
+ const lcpRecord = PrioritizeLcpImage.getLcpRecord(trace, processedNavigation, networkRecords);
252
307
  const graph = lanternLCP.pessimisticGraph;
253
- // eslint-disable-next-line max-len
254
- const {lcpNodeToPreload, initiatorPath} = PrioritizeLcpImage.getLCPNodeToPreload(mainResource, graph, lcpUrl);
308
+ // Note: if moving to LCPAllFrames, mainResource would need to be the LCP frame's main resource.
309
+ const {lcpNodeToPreload, initiatorPath} = PrioritizeLcpImage.getLCPNodeToPreload(mainResource,
310
+ graph, lcpRecord);
255
311
 
256
312
  const {results, wastedMs} =
257
313
  PrioritizeLcpImage.computeWasteWithGraph(lcpElement, lcpNodeToPreload, graph, simulator);
@@ -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