lighthouse 11.4.0-dev.20231218 → 11.4.0-dev.20231219
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.
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +14 -4
- package/core/computed/metrics/cumulative-layout-shift.d.ts +20 -1
- package/core/computed/metrics/cumulative-layout-shift.js +74 -4
- package/core/gather/gatherers/dobetterweb/response-compression.js +1 -12
- package/core/gather/gatherers/trace.js +3 -3
- package/core/lib/network-request.js +10 -2
- package/core/lib/polyfill-dom-rect.d.ts +2 -0
- package/core/lib/polyfill-dom-rect.js +111 -0
- package/core/lib/trace-engine.d.ts +4 -0
- package/core/lib/trace-engine.js +16 -0
- package/package.json +2 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`getAssertionReport works (multiple failing) 1`] = `
|
|
4
4
|
"X difference at cumulative-layout-shift audit.details.items.length
|
|
5
5
|
expected: []
|
|
6
|
-
found: [{\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444}]
|
|
6
|
+
found: [{\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.13570762803819444,\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444},\\"newEngineResultDiffered\\":false}]
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
X difference at cumulative-layout-shift audit.details.blah
|
|
@@ -28,7 +28,12 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
|
|
|
28
28
|
\\"type\\": \\"debugdata\\",
|
|
29
29
|
\\"items\\": [
|
|
30
30
|
{
|
|
31
|
-
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444
|
|
31
|
+
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444,
|
|
32
|
+
\\"newEngineResult\\": {
|
|
33
|
+
\\"cumulativeLayoutShift\\": 0.13570762803819444,
|
|
34
|
+
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444
|
|
35
|
+
},
|
|
36
|
+
\\"newEngineResultDiffered\\": false
|
|
32
37
|
}
|
|
33
38
|
]
|
|
34
39
|
}
|
|
@@ -38,7 +43,7 @@ exports[`getAssertionReport works (multiple failing) 1`] = `
|
|
|
38
43
|
exports[`getAssertionReport works (trivial failing) 1`] = `
|
|
39
44
|
"X difference at cumulative-layout-shift audit.details.items.length
|
|
40
45
|
expected: []
|
|
41
|
-
found: [{\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444}]
|
|
46
|
+
found: [{\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444,\\"newEngineResult\\":{\\"cumulativeLayoutShift\\":0.13570762803819444,\\"cumulativeLayoutShiftMainFrame\\":0.13570762803819444},\\"newEngineResultDiffered\\":false}]
|
|
42
47
|
|
|
43
48
|
found result:
|
|
44
49
|
{
|
|
@@ -58,7 +63,12 @@ exports[`getAssertionReport works (trivial failing) 1`] = `
|
|
|
58
63
|
\\"type\\": \\"debugdata\\",
|
|
59
64
|
\\"items\\": [
|
|
60
65
|
{
|
|
61
|
-
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444
|
|
66
|
+
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444,
|
|
67
|
+
\\"newEngineResult\\": {
|
|
68
|
+
\\"cumulativeLayoutShift\\": 0.13570762803819444,
|
|
69
|
+
\\"cumulativeLayoutShiftMainFrame\\": 0.13570762803819444
|
|
70
|
+
},
|
|
71
|
+
\\"newEngineResultDiffered\\": false
|
|
62
72
|
}
|
|
63
73
|
]
|
|
64
74
|
}
|
|
@@ -4,6 +4,7 @@ export type LayoutShiftEvent = {
|
|
|
4
4
|
isMainFrame: boolean;
|
|
5
5
|
weightedScore: number;
|
|
6
6
|
impactedNodes?: LH.Artifacts.TraceImpactedNode[];
|
|
7
|
+
event: LH.TraceEvent;
|
|
7
8
|
};
|
|
8
9
|
declare const CumulativeLayoutShiftComputed: typeof CumulativeLayoutShift & {
|
|
9
10
|
request: (dependencies: import("../../index.js").Trace, context: import("../../../types/utility-types.js").default.ImmutableObject<{
|
|
@@ -12,6 +13,11 @@ declare const CumulativeLayoutShiftComputed: typeof CumulativeLayoutShift & {
|
|
|
12
13
|
cumulativeLayoutShift: number;
|
|
13
14
|
cumulativeLayoutShiftMainFrame: number;
|
|
14
15
|
impactByNodeId: Map<number, number>;
|
|
16
|
+
newEngineResult?: {
|
|
17
|
+
cumulativeLayoutShift: number;
|
|
18
|
+
cumulativeLayoutShiftMainFrame: number;
|
|
19
|
+
} | undefined;
|
|
20
|
+
newEngineResultDiffered: boolean;
|
|
15
21
|
}>;
|
|
16
22
|
};
|
|
17
23
|
declare class CumulativeLayoutShift {
|
|
@@ -43,15 +49,28 @@ declare class CumulativeLayoutShift {
|
|
|
43
49
|
* @return {number}
|
|
44
50
|
*/
|
|
45
51
|
static calculate(layoutShiftEvents: Array<LayoutShiftEvent>): number;
|
|
52
|
+
/**
|
|
53
|
+
* @param {LayoutShiftEvent[]} allFrameShiftEvents
|
|
54
|
+
* @param {LayoutShiftEvent[]} mainFrameShiftEvents
|
|
55
|
+
*/
|
|
56
|
+
static computeWithSharedTraceEngine(allFrameShiftEvents: LayoutShiftEvent[], mainFrameShiftEvents: LayoutShiftEvent[]): Promise<{
|
|
57
|
+
cumulativeLayoutShift: any;
|
|
58
|
+
cumulativeLayoutShiftMainFrame: any;
|
|
59
|
+
}>;
|
|
46
60
|
/**
|
|
47
61
|
* @param {LH.Trace} trace
|
|
48
62
|
* @param {LH.Artifacts.ComputedContext} context
|
|
49
|
-
* @return {Promise<{cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number, impactByNodeId: Map<number, number
|
|
63
|
+
* @return {Promise<{cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number, impactByNodeId: Map<number, number>, newEngineResult?: {cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number}, newEngineResultDiffered: boolean}>}
|
|
50
64
|
*/
|
|
51
65
|
static compute_(trace: LH.Trace, context: LH.Artifacts.ComputedContext): Promise<{
|
|
52
66
|
cumulativeLayoutShift: number;
|
|
53
67
|
cumulativeLayoutShiftMainFrame: number;
|
|
54
68
|
impactByNodeId: Map<number, number>;
|
|
69
|
+
newEngineResult?: {
|
|
70
|
+
cumulativeLayoutShift: number;
|
|
71
|
+
cumulativeLayoutShiftMainFrame: number;
|
|
72
|
+
} | undefined;
|
|
73
|
+
newEngineResultDiffered: boolean;
|
|
55
74
|
}>;
|
|
56
75
|
}
|
|
57
76
|
import { ProcessedTrace } from '../processed-trace.js';
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
import {makeComputedArtifact} from '../computed-artifact.js';
|
|
8
8
|
import {ProcessedTrace} from '../processed-trace.js';
|
|
9
9
|
import * as RectHelpers from '../../lib/rect-helpers.js';
|
|
10
|
+
import * as TraceEngine from '../../lib/trace-engine.js';
|
|
11
|
+
import {Sentry} from '../../lib/sentry.js';
|
|
10
12
|
|
|
11
|
-
/** @typedef {{ts: number, isMainFrame: boolean, weightedScore: number, impactedNodes?: LH.Artifacts.TraceImpactedNode[]}} LayoutShiftEvent */
|
|
13
|
+
/** @typedef {{ts: number, isMainFrame: boolean, weightedScore: number, impactedNodes?: LH.Artifacts.TraceImpactedNode[], event: LH.TraceEvent}} LayoutShiftEvent */
|
|
12
14
|
|
|
13
15
|
const RECENT_INPUT_WINDOW = 500;
|
|
14
16
|
|
|
@@ -67,6 +69,7 @@ class CumulativeLayoutShift {
|
|
|
67
69
|
isMainFrame: event.args.data.is_main_frame,
|
|
68
70
|
weightedScore: event.args.data.weighted_score_delta,
|
|
69
71
|
impactedNodes: event.args.data.impacted_nodes,
|
|
72
|
+
event,
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
|
|
@@ -145,10 +148,29 @@ class CumulativeLayoutShift {
|
|
|
145
148
|
return maxScore;
|
|
146
149
|
}
|
|
147
150
|
|
|
151
|
+
/**
|
|
152
|
+
* @param {LayoutShiftEvent[]} allFrameShiftEvents
|
|
153
|
+
* @param {LayoutShiftEvent[]} mainFrameShiftEvents
|
|
154
|
+
*/
|
|
155
|
+
static async computeWithSharedTraceEngine(allFrameShiftEvents, mainFrameShiftEvents) {
|
|
156
|
+
/** @param {LH.TraceEvent[]} events */
|
|
157
|
+
const run = async (events) => {
|
|
158
|
+
const processor = new TraceEngine.TraceProcessor({
|
|
159
|
+
LayoutShifts: TraceEngine.TraceHandlers.LayoutShifts,
|
|
160
|
+
Screenshots: TraceEngine.TraceHandlers.Screenshots,
|
|
161
|
+
});
|
|
162
|
+
await processor.parse(events);
|
|
163
|
+
return processor.data.LayoutShifts.sessionMaxScore;
|
|
164
|
+
};
|
|
165
|
+
const cumulativeLayoutShift = await run(allFrameShiftEvents.map(e => e.event));
|
|
166
|
+
const cumulativeLayoutShiftMainFrame = await run(mainFrameShiftEvents.map(e => e.event));
|
|
167
|
+
return {cumulativeLayoutShift, cumulativeLayoutShiftMainFrame};
|
|
168
|
+
}
|
|
169
|
+
|
|
148
170
|
/**
|
|
149
171
|
* @param {LH.Trace} trace
|
|
150
172
|
* @param {LH.Artifacts.ComputedContext} context
|
|
151
|
-
* @return {Promise<{cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number, impactByNodeId: Map<number, number
|
|
173
|
+
* @return {Promise<{cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number, impactByNodeId: Map<number, number>, newEngineResult?: {cumulativeLayoutShift: number, cumulativeLayoutShiftMainFrame: number}, newEngineResultDiffered: boolean}>}
|
|
152
174
|
*/
|
|
153
175
|
static async compute_(trace, context) {
|
|
154
176
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
@@ -157,11 +179,59 @@ class CumulativeLayoutShift {
|
|
|
157
179
|
CumulativeLayoutShift.getLayoutShiftEvents(processedTrace);
|
|
158
180
|
const impactByNodeId = CumulativeLayoutShift.getImpactByNodeId(allFrameShiftEvents);
|
|
159
181
|
const mainFrameShiftEvents = allFrameShiftEvents.filter(e => e.isMainFrame);
|
|
182
|
+
const cumulativeLayoutShift = CumulativeLayoutShift.calculate(allFrameShiftEvents);
|
|
183
|
+
const cumulativeLayoutShiftMainFrame = CumulativeLayoutShift.calculate(mainFrameShiftEvents);
|
|
184
|
+
|
|
185
|
+
// Run with the new trace engine, and only throw an error if we are running our unit tests.
|
|
186
|
+
// Otherwise, simply report any differences or errors to Sentry.
|
|
187
|
+
// TODO: TraceEngine always drops `had_recent_input` events, but Lighthouse is more lenient.
|
|
188
|
+
// See comment in `getLayoutShiftEvents`. We need to upstream this.
|
|
189
|
+
let newEngineResult;
|
|
190
|
+
let newEngineResultDiffered = false;
|
|
191
|
+
let tryNewTraceEngine = true;
|
|
192
|
+
if (allFrameShiftEvents.some(e => e.event.args.data?.had_recent_input)) {
|
|
193
|
+
tryNewTraceEngine = false;
|
|
194
|
+
}
|
|
195
|
+
if (tryNewTraceEngine) {
|
|
196
|
+
try {
|
|
197
|
+
newEngineResult =
|
|
198
|
+
await this.computeWithSharedTraceEngine(allFrameShiftEvents, mainFrameShiftEvents);
|
|
199
|
+
newEngineResultDiffered =
|
|
200
|
+
newEngineResult.cumulativeLayoutShift !== cumulativeLayoutShift ||
|
|
201
|
+
newEngineResult.cumulativeLayoutShiftMainFrame !== cumulativeLayoutShiftMainFrame;
|
|
202
|
+
if (newEngineResultDiffered) {
|
|
203
|
+
newEngineResultDiffered = true;
|
|
204
|
+
const expected = JSON.stringify({cumulativeLayoutShift, cumulativeLayoutShiftMainFrame});
|
|
205
|
+
const got = JSON.stringify(newEngineResult);
|
|
206
|
+
throw new Error(`new trace engine differed. expected: ${expected}, got: ${got}`);
|
|
207
|
+
}
|
|
208
|
+
} catch (err) {
|
|
209
|
+
console.error(err);
|
|
210
|
+
newEngineResultDiffered = true;
|
|
211
|
+
|
|
212
|
+
const error = new Error('Error when using new trace engine', {cause: err});
|
|
213
|
+
// @ts-expect-error Check for running from tests.
|
|
214
|
+
if (global.expect) {
|
|
215
|
+
throw error;
|
|
216
|
+
} else {
|
|
217
|
+
Sentry.captureException(error, {
|
|
218
|
+
tags: {computed: 'new-trace-engine'},
|
|
219
|
+
level: 'error',
|
|
220
|
+
extra: {
|
|
221
|
+
// Not sure if Sentry handles `cause`, so just in case add the info in a second place.
|
|
222
|
+
errorMsg: err.toString(),
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
160
228
|
|
|
161
229
|
return {
|
|
162
|
-
cumulativeLayoutShift
|
|
163
|
-
cumulativeLayoutShiftMainFrame
|
|
230
|
+
cumulativeLayoutShift,
|
|
231
|
+
cumulativeLayoutShiftMainFrame,
|
|
164
232
|
impactByNodeId,
|
|
233
|
+
newEngineResult,
|
|
234
|
+
newEngineResultDiffered,
|
|
165
235
|
};
|
|
166
236
|
}
|
|
167
237
|
}
|
|
@@ -23,12 +23,6 @@ import {fetchResponseBodyFromCache} from '../../driver/network.js';
|
|
|
23
23
|
import {NetworkRecords} from '../../../computed/network-records.js';
|
|
24
24
|
|
|
25
25
|
const CHROME_EXTENSION_PROTOCOL = 'chrome-extension:';
|
|
26
|
-
const compressionHeaders = [
|
|
27
|
-
'content-encoding',
|
|
28
|
-
'x-original-content-encoding',
|
|
29
|
-
'x-content-encoding-over-network',
|
|
30
|
-
];
|
|
31
|
-
const compressionTypes = ['gzip', 'br', 'deflate'];
|
|
32
26
|
const binaryMimeTypes = ['image', 'audio', 'video'];
|
|
33
27
|
/** @type {LH.Crdp.Network.ResourceType[]} */
|
|
34
28
|
const textResourceTypes = [
|
|
@@ -71,12 +65,7 @@ class ResponseCompression extends BaseGatherer {
|
|
|
71
65
|
return;
|
|
72
66
|
}
|
|
73
67
|
|
|
74
|
-
|
|
75
|
-
compressionHeaders.includes(header.name.toLowerCase()) &&
|
|
76
|
-
compressionTypes.includes(header.value)
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
if (!isContentEncoded) {
|
|
68
|
+
if (!NetworkRequest.isContentEncoded(record)) {
|
|
80
69
|
unoptimizedResponses.push({
|
|
81
70
|
requestId: record.requestId,
|
|
82
71
|
url: record.url,
|
|
@@ -56,9 +56,9 @@ class Trace extends BaseGatherer {
|
|
|
56
56
|
'disabled-by-default-devtools.timeline.frame',
|
|
57
57
|
'latencyInfo',
|
|
58
58
|
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
59
|
+
// Not used by Lighthouse (yet) but included for users that want JS samples when looking at
|
|
60
|
+
// a trace collected by Lighthouse (e.g. "View Trace" workflow in DevTools)
|
|
61
|
+
'disabled-by-default-v8.cpu_profiler',
|
|
62
62
|
];
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -616,8 +616,16 @@ class NetworkRequest {
|
|
|
616
616
|
static isContentEncoded(record) {
|
|
617
617
|
// FYI: older devtools logs (like our test fixtures) seems to be lower case, while modern logs
|
|
618
618
|
// are Cased-Like-This.
|
|
619
|
-
const
|
|
620
|
-
|
|
619
|
+
const patterns = global.isLightrider ? [
|
|
620
|
+
/^x-original-content-encoding$/i,
|
|
621
|
+
] : [
|
|
622
|
+
/^content-encoding$/i,
|
|
623
|
+
/^x-content-encoding-over-network$/i,
|
|
624
|
+
];
|
|
625
|
+
const compressionTypes = ['gzip', 'br', 'deflate'];
|
|
626
|
+
return record.responseHeaders.some(header =>
|
|
627
|
+
patterns.some(p => header.name.match(p)) && compressionTypes.includes(header.value)
|
|
628
|
+
);
|
|
621
629
|
}
|
|
622
630
|
|
|
623
631
|
/**
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
function polyfillDOMRect() {
|
|
5
|
+
// devtools assumes clientside :(
|
|
6
|
+
|
|
7
|
+
// Everything else in here is the DOMRect polyfill
|
|
8
|
+
// https://raw.githubusercontent.com/JakeChampion/polyfill-library/master/polyfills/DOMRect/polyfill.js
|
|
9
|
+
|
|
10
|
+
(function (global) {
|
|
11
|
+
function number(v) {
|
|
12
|
+
return v === undefined ? 0 : Number(v);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function different(u, v) {
|
|
16
|
+
return u !== v && !(isNaN(u) && isNaN(v));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function DOMRect(xArg, yArg, wArg, hArg) {
|
|
20
|
+
let x, y, width, height, left, right, top, bottom;
|
|
21
|
+
|
|
22
|
+
x = number(xArg);
|
|
23
|
+
y = number(yArg);
|
|
24
|
+
width = number(wArg);
|
|
25
|
+
height = number(hArg);
|
|
26
|
+
|
|
27
|
+
Object.defineProperties(this, {
|
|
28
|
+
x: {
|
|
29
|
+
get: function () { return x; },
|
|
30
|
+
set: function (newX) {
|
|
31
|
+
if (different(x, newX)) {
|
|
32
|
+
x = newX;
|
|
33
|
+
left = right = undefined;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
enumerable: true
|
|
37
|
+
},
|
|
38
|
+
y: {
|
|
39
|
+
get: function () { return y; },
|
|
40
|
+
set: function (newY) {
|
|
41
|
+
if (different(y, newY)) {
|
|
42
|
+
y = newY;
|
|
43
|
+
top = bottom = undefined;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
enumerable: true
|
|
47
|
+
},
|
|
48
|
+
width: {
|
|
49
|
+
get: function () { return width; },
|
|
50
|
+
set: function (newWidth) {
|
|
51
|
+
if (different(width, newWidth)) {
|
|
52
|
+
width = newWidth;
|
|
53
|
+
left = right = undefined;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
enumerable: true
|
|
57
|
+
},
|
|
58
|
+
height: {
|
|
59
|
+
get: function () { return height; },
|
|
60
|
+
set: function (newHeight) {
|
|
61
|
+
if (different(height, newHeight)) {
|
|
62
|
+
height = newHeight;
|
|
63
|
+
top = bottom = undefined;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
enumerable: true
|
|
67
|
+
},
|
|
68
|
+
left: {
|
|
69
|
+
get: function () {
|
|
70
|
+
if (left === undefined) {
|
|
71
|
+
left = x + Math.min(0, width);
|
|
72
|
+
}
|
|
73
|
+
return left;
|
|
74
|
+
},
|
|
75
|
+
enumerable: true
|
|
76
|
+
},
|
|
77
|
+
right: {
|
|
78
|
+
get: function () {
|
|
79
|
+
if (right === undefined) {
|
|
80
|
+
right = x + Math.max(0, width);
|
|
81
|
+
}
|
|
82
|
+
return right;
|
|
83
|
+
},
|
|
84
|
+
enumerable: true
|
|
85
|
+
},
|
|
86
|
+
top: {
|
|
87
|
+
get: function () {
|
|
88
|
+
if (top === undefined) {
|
|
89
|
+
top = y + Math.min(0, height);
|
|
90
|
+
}
|
|
91
|
+
return top;
|
|
92
|
+
},
|
|
93
|
+
enumerable: true
|
|
94
|
+
},
|
|
95
|
+
bottom: {
|
|
96
|
+
get: function () {
|
|
97
|
+
if (bottom === undefined) {
|
|
98
|
+
bottom = y + Math.max(0, height);
|
|
99
|
+
}
|
|
100
|
+
return bottom;
|
|
101
|
+
},
|
|
102
|
+
enumerable: true
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
globalThis.DOMRect = DOMRect;
|
|
108
|
+
})(globalThis);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {polyfillDOMRect};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// @ts-expect-error missing types
|
|
2
|
+
import * as TraceEngine from '@paulirish/trace_engine';
|
|
3
|
+
|
|
4
|
+
import {polyfillDOMRect} from './polyfill-dom-rect.js';
|
|
5
|
+
|
|
6
|
+
polyfillDOMRect();
|
|
7
|
+
|
|
8
|
+
const TraceProcessor = TraceEngine.Processor.TraceProcessor;
|
|
9
|
+
const TraceHandlers = TraceEngine.Handlers.ModelHandlers;
|
|
10
|
+
const RootCauses = TraceEngine.RootCauses.RootCauses.RootCauses;
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
TraceProcessor,
|
|
14
|
+
TraceHandlers,
|
|
15
|
+
RootCauses,
|
|
16
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "11.4.0-dev.
|
|
4
|
+
"version": "11.4.0-dev.20231219",
|
|
5
5
|
"description": "Automated auditing, performance metrics, and best practices for the web.",
|
|
6
6
|
"main": "./core/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -180,6 +180,7 @@
|
|
|
180
180
|
"webtreemap-cdt": "^3.2.1"
|
|
181
181
|
},
|
|
182
182
|
"dependencies": {
|
|
183
|
+
"@paulirish/trace_engine": "^0.0.7",
|
|
183
184
|
"@sentry/node": "^6.17.4",
|
|
184
185
|
"axe-core": "^4.8.1",
|
|
185
186
|
"chrome-launcher": "^1.1.0",
|