Skip to content

Commit

Permalink
core(trace-elements): add sentry debugging for impactedNodes (#15915)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamraine committed Apr 5, 2024
1 parent a7557d6 commit 0efaa83
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
2 changes: 1 addition & 1 deletion core/audits/layout-shifts.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class LayoutShifts extends Audit {
.slice(0, MAX_LAYOUT_SHIFTS);
for (const event of topLayoutShiftEvents) {
const biggestImpactNodeId = TraceElements.getBiggestImpactNodeForShiftEvent(
event.args.data.impacted_nodes || [], impactByNodeId);
event.args.data.impacted_nodes || [], impactByNodeId, event);
const biggestImpactElement = traceElements.find(t => t.nodeId === biggestImpactNodeId);

// Turn root causes into sub-items.
Expand Down
50 changes: 40 additions & 10 deletions core/gather/gatherers/trace-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,49 @@ class TraceElements extends BaseGatherer {
*
* @param {LH.Artifacts.TraceImpactedNode[]} impactedNodes
* @param {Map<number, number>} impactByNodeId
* @param {import('../../lib/trace-engine.js').SaneSyntheticLayoutShift} event Only for debugging
* @return {number|undefined}
*/
static getBiggestImpactNodeForShiftEvent(impactedNodes, impactByNodeId) {
let biggestImpactNodeId;
let biggestImpactNodeScore = Number.NEGATIVE_INFINITY;
for (const node of impactedNodes) {
const impactScore = impactByNodeId.get(node.node_id);
if (impactScore !== undefined && impactScore > biggestImpactNodeScore) {
biggestImpactNodeId = node.node_id;
biggestImpactNodeScore = impactScore;
static getBiggestImpactNodeForShiftEvent(impactedNodes, impactByNodeId, event) {
try {
let biggestImpactNodeId;
let biggestImpactNodeScore = Number.NEGATIVE_INFINITY;
for (const node of impactedNodes) {
const impactScore = impactByNodeId.get(node.node_id);
if (impactScore !== undefined && impactScore > biggestImpactNodeScore) {
biggestImpactNodeId = node.node_id;
biggestImpactNodeScore = impactScore;
}
}
return biggestImpactNodeId;
} catch (err) {
// See https://github.com/GoogleChrome/lighthouse/issues/15870
// `impactedNodes` should always be an array here, but it can randomly be something else for
// currently unknown reasons. This exception handling will help us identify what
// `impactedNodes` really is and also prevent the error from being fatal.

// It's possible `impactedNodes` is not JSON serializable, so let's add more supplemental
// fields just in case.
const impactedNodesType = typeof impactedNodes;
const impactedNodesClassName = impactedNodes?.constructor?.name;

let impactedNodesJson;
let eventJson;
try {
impactedNodesJson = JSON.parse(JSON.stringify(impactedNodes));
eventJson = JSON.parse(JSON.stringify(event));
} catch {}

Sentry.captureException(err, {
extra: {
impactedNodes: impactedNodesJson,
event: eventJson,
impactedNodesType,
impactedNodesClassName,
},
});
return;
}
return biggestImpactNodeId;
}

/**
Expand Down Expand Up @@ -129,7 +159,7 @@ class TraceElements extends BaseGatherer {
const nodeIds = [];
const impactedNodes = event.args.data.impacted_nodes || [];
const biggestImpactedNodeId =
this.getBiggestImpactNodeForShiftEvent(impactedNodes, impactByNodeId);
this.getBiggestImpactNodeForShiftEvent(impactedNodes, impactByNodeId, event);
if (biggestImpactedNodeId !== undefined) {
nodeIds.push(biggestImpactedNodeId);
}
Expand Down
7 changes: 7 additions & 0 deletions core/test/gather/gatherers/trace-elements-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ describe('Trace Elements gatherer - GetTopLayoutShiftElements', () => {
{nodeId: 15}, // score: 0.1
]);
});

describe('getBiggestImpactForShiftEvent', () => {
it('is non fatal if impactedNodes is not iterable', () => {
const result = TraceElementsGatherer.getBiggestImpactNodeForShiftEvent(1, new Map());
expect(result).toBeUndefined();
});
});
});

describe('Trace Elements gatherer - Animated Elements', () => {
Expand Down

0 comments on commit 0efaa83

Please sign in to comment.