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 /
|
|
7
|
+
* GET /requestedUrl => 302 /firstRedirect
|
|
8
8
|
* GET /firstRedirect => 200 /firstRedirect, window.location = '/secondRedirect'
|
|
9
9
|
* GET /secondRedirect => 302 /thirdRedirect
|
|
10
|
-
* GET /thirdRedirect =>
|
|
10
|
+
* GET /thirdRedirect => 302 /mainDocumentUrl
|
|
11
|
+
* GET /mainDocumentUrl => 200 /mainDocumentUrl
|
|
11
12
|
*
|
|
12
|
-
* Returns network records [/
|
|
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(
|
|
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
|
package/core/audits/redirects.js
CHANGED
|
@@ -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 /
|
|
42
|
+
* GET /requestedUrl => 302 /firstRedirect
|
|
44
43
|
* GET /firstRedirect => 200 /firstRedirect, window.location = '/secondRedirect'
|
|
45
44
|
* GET /secondRedirect => 302 /thirdRedirect
|
|
46
|
-
* GET /thirdRedirect =>
|
|
45
|
+
* GET /thirdRedirect => 302 /mainDocumentUrl
|
|
46
|
+
* GET /mainDocumentUrl => 200 /mainDocumentUrl
|
|
47
47
|
*
|
|
48
|
-
* Returns network records [/
|
|
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(
|
|
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.
|
|
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
|
-
|
|
74
|
-
|
|
73
|
+
if (!documentRequests.length) {
|
|
74
|
+
throw new Error('No navigation requests found');
|
|
75
|
+
}
|
|
75
76
|
|
|
76
|
-
|
|
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
|
|
98
|
+
const nodeTimingsById = new Map();
|
|
100
99
|
for (const [node, timing] of metricResult.pessimisticEstimate.nodeTimings.entries()) {
|
|
101
100
|
if (node.type === 'network') {
|
|
102
|
-
|
|
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 =
|
|
122
|
-
const redirectedTiming =
|
|
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
|
|
492
|
-
|
|
493
|
-
|
|
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 =
|
|
498
|
-
?
|
|
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
|
-
|
|
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
package/types/artifacts.d.ts
CHANGED
|
@@ -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
|
|
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;
|