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
- .find(element => element.traceEventType === 'largest-contentful-paint');
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: 1, notApplicable: true};
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|undefined} lcpElement
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|undefined} lcpElement
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 (!lcpElement || !lcpNode) {
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 lcpNodeId = largestContentfulPaintEvt?.args?.data?.nodeId;
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', lcpNodeId ? [{nodeId: lcpNodeId}] : []],
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lighthouse",
3
3
  "type": "module",
4
- "version": "9.5.0-dev.20220831",
4
+ "version": "9.5.0-dev.20220901",
5
5
  "description": "Automated auditing, performance metrics, and best practices for the web.",
6
6
  "main": "./core/index.js",
7
7
  "bin": {
@@ -578,6 +578,7 @@ declare module Artifacts {
578
578
  node: NodeDetails;
579
579
  nodeId?: number;
580
580
  animations?: {name?: string, failureReasonsMask?: number, unsupportedProperties?: string[]}[];
581
+ type?: string;
581
582
  }
582
583
 
583
584
  interface ViewportDimensions {