Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions core/audits/insights/insight-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ async function getInsightSet(artifacts, context) {
await TraceEngineResult.request({trace, settings, SourceMaps, HostDPR}, context);

const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
const key = navigationId ?? NO_NAVIGATION;
const insights = traceEngineResult.insights.get(key);
const insights = navigationId ?
[...traceEngineResult.insights.values()]
.find(insightSet => insightSet.navigation?.args.data?.navigationId) :
traceEngineResult.insights.get(NO_NAVIGATION);

return {insights, data: traceEngineResult.data};
}
Expand All @@ -43,7 +45,7 @@ async function getInsightSet(artifacts, context) {
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @param {T} insightName
* @param {(insight: import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T], extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings?: Array<string | LH.IcuMessage>, numericValue?: number, numericUnit?: LH.Audit.NumericProduct['numericUnit']}|LH.Audit.Details|undefined} createDetails
* @param {(insight: NonNullable<import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModels[T]>, extras: CreateDetailsExtras) => {details: LH.Audit.Details, warnings?: Array<string | LH.IcuMessage>, numericValue?: number, numericUnit?: LH.Audit.NumericProduct['numericUnit']}|LH.Audit.Details|undefined} createDetails
* @template {keyof import('@paulirish/trace_engine/models/trace/insights/types.js').InsightModelsType} T
* @return {Promise<LH.Audit.Product>}
*/
Expand All @@ -56,11 +58,19 @@ async function adaptInsightToAuditProduct(artifacts, context, insightName, creat
};
}

const error = insights.modelErrors[insightName];
if (error) {
return {
errorMessage: error.message,
errorStack: error.stack,
score: null,
};
}

const insight = insights.model[insightName];
if (insight instanceof Error) {
if (!insight) {
return {
errorMessage: insight.message,
errorStack: insight.stack,
scoreDisplayMode: Audit.SCORING_MODES.NOT_APPLICABLE,
score: null,
};
}
Expand Down
2 changes: 1 addition & 1 deletion core/audits/layout-shifts.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class LayoutShifts extends Audit {
layoutShifts: new Map(),
};
for (const insightSet of traceEngineResult.insights.values()) {
for (const [shift, reasons] of insightSet.model.CLSCulprits.shifts) {
for (const [shift, reasons] of insightSet.model.CLSCulprits?.shifts ?? []) {
allRootCauses.layoutShifts.set(shift, reasons);
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/audits/server-response-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ class ServerResponseTime extends Audit {
const {SourceMaps, HostDPR} = artifacts;
const navInsights =
await NavigationInsights.request({trace, settings, SourceMaps, HostDPR}, context);
const responseTime = navInsights.model.DocumentLatency.data?.serverResponseTime;
const url = navInsights.model.DocumentLatency.data?.documentRequest?.args.data.url;
const responseTime = navInsights.model.DocumentLatency?.data?.serverResponseTime;
const url = navInsights.model.DocumentLatency?.data?.documentRequest?.args.data.url;

if (responseTime === undefined || !url) {
throw new Error('no timing found for main resource');
}

const passed =
Boolean(navInsights.model.DocumentLatency.data?.checklist.serverResponseIsFast.value);
Boolean(navInsights.model.DocumentLatency?.data?.checklist.serverResponseIsFast.value);
const displayValue = str_(UIStrings.displayValue, {timeInMs: responseTime});

/** @type {LH.Audit.Details.Opportunity['headings']} */
Expand Down
1 change: 0 additions & 1 deletion core/computed/document-urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class DocumentUrls {
if (!requestedUrl || !mainDocumentUrl) throw new Error('No main frame navigations found');

const initialRequest = Lantern.Core.NetworkAnalyzer.findResourceForUrl(
// @ts-expect-error - trace engine types for InitiatorType are outdated
networkRecords,
requestedUrl
);
Expand Down
2 changes: 0 additions & 2 deletions core/computed/main-resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ class MainResource {
// would have evicted the first request by the time `MainDocumentRequest` (a consumer
// of this computed artifact) attempts to fetch the contents, resulting in a protocol error.
const mainResource = Lantern.Core.NetworkAnalyzer.findLastDocumentForUrl(
// @ts-expect-error - trace engine types for InitiatorType are outdated
records,
mainDocumentUrl
);
if (!mainResource) {
throw new Error('Unable to identify the main resource');
}

// @ts-expect-error - Return type is typed as Lantern request by trace engine, but it is a raw record at runtime since we passed raw records.
return mainResource;
}
}
Expand Down
8 changes: 4 additions & 4 deletions core/computed/metrics/lantern-metric.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ async function getComputationDataParamsFromTrace(data, context) {
const graph = await PageDependencyGraph.request({...data, fromTrace: true}, context);
const traceEngineResult = await TraceEngineResult.request(data, context);
const frameId = traceEngineResult.data.Meta.mainFrameId;
const navigationId =
traceEngineResult.data.Meta.mainFrameNavigations[0].args.data?.navigationId;
if (!navigationId) {
const navigation =
traceEngineResult.data.Meta.mainFrameNavigations[0];
if (!navigation) {
throw new Error(`Lantern metrics could not be calculated due to missing navigation id`);
}

const processedNavigation = Lantern.TraceEngineComputationData.createProcessedNavigation(
traceEngineResult.data, frameId, navigationId);
traceEngineResult.data, frameId, navigation);
const simulator = data.simulator || (await LoadSimulator.request(data, context));

return {simulator, graph, processedNavigation};
Expand Down
2 changes: 1 addition & 1 deletion core/computed/metrics/lcp-breakdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class LCPBreakdown {
throw new LighthouseError(LighthouseError.errors.NO_LCP, {}, {cause: lcpBreakdown});
}

if (!lcpBreakdown.subparts) {
if (!lcpBreakdown || !lcpBreakdown.subparts) {
throw new LighthouseError(LighthouseError.errors.NO_LCP);
}

Expand Down
2 changes: 1 addition & 1 deletion core/computed/metrics/time-to-first-byte.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class TimeToFirstByte extends NavigationMetric {
const lcpBreakdown = navInsights.model.LCPBreakdown;

// Defer to LCP breakdown, but if there's no LCP fallback to manual calculation.
if (!(lcpBreakdown instanceof Error) && lcpBreakdown.subparts) {
if (lcpBreakdown && !(lcpBreakdown instanceof Error) && lcpBreakdown.subparts) {
return {
timing: lcpBreakdown.subparts.ttfb.range / 1000,
timestamp: lcpBreakdown.subparts.ttfb.max,
Expand Down
3 changes: 2 additions & 1 deletion core/computed/navigation-insights.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class NavigationInsights {
const navigationId = processedTrace.timeOriginEvt.args.data?.navigationId;
if (!navigationId) throw new Error('No navigationId found');

const navInsights = traceEngineResult.insights.get(navigationId);
const navInsights = [...traceEngineResult.insights.values()]
.find(insightSet => insightSet.navigation?.args.data?.navigationId === navigationId);
if (!navInsights) throw new Error('No navigations insights found');

return navInsights;
Expand Down
1 change: 0 additions & 1 deletion core/computed/network-analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class NetworkAnalysis {
static async compute_(devtoolsLog, context) {
const records = await NetworkRecords.request(devtoolsLog, context);
const analysis = Lantern.Core.NetworkAnalyzer.analyze(
// @ts-expect-error - trace engine types for InitiatorType are outdated
records
);
if (!analysis) {
Expand Down
2 changes: 1 addition & 1 deletion core/gather/gatherers/trace-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class TraceElements extends BaseGatherer {
}, new Set());

// TODO: handle digging into Map in recursiveObjectEnumerate.
for (const shift of insightSet.model.CLSCulprits.shifts.values()) {
for (const shift of insightSet.model.CLSCulprits?.shifts.values() ?? []) {
nodeIds.push(...shift.unsizedImages.map(s => s.backendNodeId));
}

Expand Down
6 changes: 0 additions & 6 deletions core/lib/navigation-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ function getNonHtmlError(finalRecord) {
function getPageLoadError(navigationError, context) {
const {url, networkRecords} = context;
const mainRecordLantern = Lantern.Core.NetworkAnalyzer.findResourceForUrl(
// @ts-expect-error - trace engine types for InitiatorType are outdated
networkRecords,
url
);
Expand All @@ -144,7 +143,6 @@ function getPageLoadError(navigationError, context) {
record.resourceType === NetworkRequest.TYPES.Document
);
if (documentRequests.length) {
// @ts-expect-error - mainRecord is inferred as a Lantern request from findResourceForUrl, but we assign a raw record here.
mainRecord = documentRequests.reduce((min, r) => {
return r.networkRequestTime < min.networkRequestTime ? r : min;
});
Expand All @@ -164,12 +162,8 @@ function getPageLoadError(navigationError, context) {
context.warnings.push(str_(UIStrings.warningXhtml));
}

// @ts-expect-error - mainRecord may be typed as a Lantern request, but functions expect a raw record.
const networkError = getNetworkError(mainRecord, context);
// @ts-expect-error - mainRecord may be typed as a Lantern request, but functions expect a raw record.
const interstitialError = getInterstitialError(mainRecord, networkRecords);
// @ts-expect-error - finalRecord may be a Lantern request, which is compatible enough
// for getNonHtmlError.
const nonHtmlError = getNonHtmlError(finalRecord);

// We want to special-case the interstitial beyond FAILED_DOCUMENT_REQUEST. See https://github.com/GoogleChrome/lighthouse/pull/8865#issuecomment-497507618
Expand Down
1 change: 0 additions & 1 deletion core/lib/network-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,6 @@ class NetworkRequest {

record.fromWorker = record.sessionTargetType === 'worker';

// @ts-expect-error - trace engine types for InitiatorType are outdated
return {
rawRequest: record,
...record,
Expand Down
5 changes: 4 additions & 1 deletion core/scripts/generate-insight-audits.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ export default ${insightName}Insight;
`.trim() + '\n';
}

const insightNames = getAllInsightNames();
const ignoredInsights = [
'CharacterSet', // TODO: add new insight audit.
];
const insightNames = getAllInsightNames().filter(name => !ignoredInsights.includes(name));

const allAuditIds = [];
for (const insightName of insightNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3427,7 +3427,7 @@
},
"render-blocking-insight": {
"id": "render-blocking-insight",
"title": "Render blocking requests",
"title": "Render-blocking requests",
"description": "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.",
"score": null,
"scoreDisplayMode": "error",
Expand Down Expand Up @@ -9403,7 +9403,7 @@
},
"render-blocking-insight": {
"id": "render-blocking-insight",
"title": "Render blocking requests",
"title": "Render-blocking requests",
"description": "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.",
"score": null,
"scoreDisplayMode": "error",
Expand Down Expand Up @@ -20665,7 +20665,7 @@
},
"render-blocking-insight": {
"id": "render-blocking-insight",
"title": "Render blocking requests",
"title": "Render-blocking requests",
"description": "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.",
"score": null,
"scoreDisplayMode": "error",
Expand Down
16 changes: 14 additions & 2 deletions core/test/results/sample_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -5619,7 +5619,7 @@
"value": false
},
"eagerlyLoaded": {
"label": "lazy load not applied",
"label": "LCP resources should not use loading=lazy",
"value": true
}
}
Expand Down Expand Up @@ -5885,7 +5885,7 @@
},
"render-blocking-insight": {
"id": "render-blocking-insight",
"title": "Render blocking requests",
"title": "Render-blocking requests",
"description": "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://developer.chrome.com/docs/performance/insights/render-blocking) can move these network requests out of the critical path.",
"score": 0.5,
"scoreDisplayMode": "metricSavings",
Expand Down Expand Up @@ -8636,6 +8636,12 @@
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:computed:TraceEngineResult:insights:CharacterSet",
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:computed:TraceEngineResult:insights:DOMSize",
Expand Down Expand Up @@ -8750,6 +8756,12 @@
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:computed:TraceEngineResult:insights:CharacterSet",
"duration": 100,
"entryType": "measure"
},
{
"startTime": 0,
"name": "lh:computed:TraceEngineResult:insights:DOMSize",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
"webtreemap-cdt": "^3.2.1"
},
"dependencies": {
"@paulirish/trace_engine": "0.0.61",
"@paulirish/trace_engine": "0.0.64",
"@sentry/node": "^9.28.1",
"axe-core": "^4.11.2",
"chrome-launcher": "^1.2.1",
Expand Down
Loading
Loading