lighthouse 9.5.0-dev.20220831 → 9.5.0-dev.20220901
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.
|
@@ -50,8 +50,9 @@ class LargestContentfulPaintLazyLoaded extends Audit {
|
|
|
50
50
|
* @return {LH.Audit.Product}
|
|
51
51
|
*/
|
|
52
52
|
static audit(artifacts) {
|
|
53
|
-
const lcpElement = artifacts.TraceElements
|
|
54
|
-
|
|
53
|
+
const lcpElement = artifacts.TraceElements.find(element => {
|
|
54
|
+
return element.traceEventType === 'largest-contentful-paint' && element.type === 'image';
|
|
55
|
+
});
|
|
55
56
|
const lcpElementImage = lcpElement ? artifacts.ImageElements.find(elem => {
|
|
56
57
|
return elem.node.devtoolsNodePath === lcpElement.node.devtoolsNodePath;
|
|
57
58
|
}) : undefined;
|
|
@@ -59,7 +60,7 @@ class LargestContentfulPaintLazyLoaded extends Audit {
|
|
|
59
60
|
|
|
60
61
|
if (!lcpElementImage ||
|
|
61
62
|
!this.isImageInViewport(lcpElementImage, artifacts.ViewportDimensions)) {
|
|
62
|
-
return {score:
|
|
63
|
+
return {score: null, notApplicable: true};
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
/** @type {LH.Audit.Details.Table['headings']} */
|
|
@@ -88,13 +88,11 @@ class PreloadLCPImageAudit extends Audit {
|
|
|
88
88
|
/**
|
|
89
89
|
* @param {LH.Artifacts.NetworkRequest} mainResource
|
|
90
90
|
* @param {LH.Gatherer.Simulation.GraphNode} graph
|
|
91
|
-
* @param {LH.Artifacts.TraceElement
|
|
91
|
+
* @param {LH.Artifacts.TraceElement} lcpElement
|
|
92
92
|
* @param {Array<LH.Artifacts.ImageElement>} imageElements
|
|
93
93
|
* @return {{lcpNodeToPreload?: LH.Gatherer.Simulation.GraphNetworkNode, initiatorPath?: InitiatorPath}}
|
|
94
94
|
*/
|
|
95
95
|
static getLCPNodeToPreload(mainResource, graph, lcpElement, imageElements) {
|
|
96
|
-
if (!lcpElement) return {};
|
|
97
|
-
|
|
98
96
|
const lcpImageElement = imageElements.find(elem => {
|
|
99
97
|
return elem.node.devtoolsNodePath === lcpElement.node.devtoolsNodePath;
|
|
100
98
|
});
|
|
@@ -121,14 +119,14 @@ class PreloadLCPImageAudit extends Audit {
|
|
|
121
119
|
|
|
122
120
|
/**
|
|
123
121
|
* Computes the estimated effect of preloading the LCP image.
|
|
124
|
-
* @param {LH.Artifacts.TraceElement
|
|
122
|
+
* @param {LH.Artifacts.TraceElement} lcpElement
|
|
125
123
|
* @param {LH.Gatherer.Simulation.GraphNetworkNode|undefined} lcpNode
|
|
126
124
|
* @param {LH.Gatherer.Simulation.GraphNode} graph
|
|
127
125
|
* @param {LH.Gatherer.Simulation.Simulator} simulator
|
|
128
126
|
* @return {{wastedMs: number, results: Array<{node: LH.Audit.Details.NodeValue, url: string, wastedMs: number}>}}
|
|
129
127
|
*/
|
|
130
128
|
static computeWasteWithGraph(lcpElement, lcpNode, graph, simulator) {
|
|
131
|
-
if (!
|
|
129
|
+
if (!lcpNode) {
|
|
132
130
|
return {
|
|
133
131
|
wastedMs: 0,
|
|
134
132
|
results: [],
|
|
@@ -222,6 +220,10 @@ class PreloadLCPImageAudit extends Audit {
|
|
|
222
220
|
const lcpElement = artifacts.TraceElements
|
|
223
221
|
.find(element => element.traceEventType === 'largest-contentful-paint');
|
|
224
222
|
|
|
223
|
+
if (!lcpElement || lcpElement.type !== 'image') {
|
|
224
|
+
return {score: null, notApplicable: true};
|
|
225
|
+
}
|
|
226
|
+
|
|
225
227
|
const [mainResource, lanternLCP, simulator] = await Promise.all([
|
|
226
228
|
MainResource.request({devtoolsLog, URL}, context),
|
|
227
229
|
LanternLCP.request(metricData, context),
|
|
@@ -25,7 +25,7 @@ import ProcessedNavigation from '../../computed/processed-navigation.js';
|
|
|
25
25
|
import {LighthouseError} from '../../lib/lh-error.js';
|
|
26
26
|
import ComputedResponsiveness from '../../computed/metrics/responsiveness.js';
|
|
27
27
|
|
|
28
|
-
/** @typedef {{nodeId: number, score?: number, animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[]}} TraceElementData */
|
|
28
|
+
/** @typedef {{nodeId: number, score?: number, animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[], type?: string}} TraceElementData */
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* @this {HTMLElement}
|
|
@@ -214,6 +214,34 @@ class TraceElements extends FRGatherer {
|
|
|
214
214
|
return animatedElementData;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
/**
|
|
218
|
+
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
219
|
+
* @param {LH.Gatherer.FRTransitionalContext} context
|
|
220
|
+
* @return {Promise<{nodeId: number, type: string} | undefined>}
|
|
221
|
+
*/
|
|
222
|
+
static async getLcpElement(processedTrace, context) {
|
|
223
|
+
let processedNavigation;
|
|
224
|
+
try {
|
|
225
|
+
processedNavigation = await ProcessedNavigation.request(processedTrace, context);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
// If we were running in timespan mode and there was no paint, treat LCP as missing.
|
|
228
|
+
if (context.gatherMode === 'timespan' && err.code === LighthouseError.errors.NO_FCP.code) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// These should exist, but trace types are loose.
|
|
236
|
+
const lcpData = processedNavigation.largestContentfulPaintEvt?.args?.data;
|
|
237
|
+
if (lcpData?.nodeId === undefined || !lcpData.type) return;
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
nodeId: lcpData.nodeId,
|
|
241
|
+
type: lcpData.type,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
217
245
|
/**
|
|
218
246
|
* @param {LH.Gatherer.FRTransitionalContext} context
|
|
219
247
|
*/
|
|
@@ -242,26 +270,16 @@ class TraceElements extends FRGatherer {
|
|
|
242
270
|
}
|
|
243
271
|
|
|
244
272
|
const processedTrace = await ProcessedTrace.request(trace, context);
|
|
245
|
-
const {largestContentfulPaintEvt} = await ProcessedNavigation
|
|
246
|
-
.request(processedTrace, context)
|
|
247
|
-
.catch(err => {
|
|
248
|
-
// If we were running in timespan mode and there was no paint, treat LCP as missing.
|
|
249
|
-
if (context.gatherMode === 'timespan' && err.code === LighthouseError.errors.NO_FCP.code) {
|
|
250
|
-
return {largestContentfulPaintEvt: undefined};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
throw err;
|
|
254
|
-
});
|
|
255
273
|
const {mainThreadEvents} = processedTrace;
|
|
256
274
|
|
|
257
|
-
const
|
|
275
|
+
const lcpNodeData = await TraceElements.getLcpElement(processedTrace, context);
|
|
258
276
|
const clsNodeData = TraceElements.getTopLayoutShiftElements(mainThreadEvents);
|
|
259
277
|
const animatedElementData = await this.getAnimatedElements(mainThreadEvents);
|
|
260
278
|
const responsivenessElementData = await TraceElements.getResponsivenessElement(trace, context);
|
|
261
279
|
|
|
262
280
|
/** @type {Map<string, TraceElementData[]>} */
|
|
263
281
|
const backendNodeDataMap = new Map([
|
|
264
|
-
['largest-contentful-paint',
|
|
282
|
+
['largest-contentful-paint', lcpNodeData ? [lcpNodeData] : []],
|
|
265
283
|
['layout-shift', clsNodeData],
|
|
266
284
|
['animation', animatedElementData],
|
|
267
285
|
['responsiveness', responsivenessElementData ? [responsivenessElementData] : []],
|
|
@@ -300,6 +318,7 @@ class TraceElements extends FRGatherer {
|
|
|
300
318
|
score: backendNodeData[i].score,
|
|
301
319
|
animations: backendNodeData[i].animations,
|
|
302
320
|
nodeId: backendNodeId,
|
|
321
|
+
type: backendNodeData[i].type,
|
|
303
322
|
});
|
|
304
323
|
}
|
|
305
324
|
}
|
package/package.json
CHANGED
package/types/artifacts.d.ts
CHANGED