Skip to content

Commit

Permalink
report: group third-party entities (#14655)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexnj authored Mar 6, 2023
1 parent 4336376 commit 5aca9f3
Show file tree
Hide file tree
Showing 37 changed files with 1,103 additions and 130 deletions.
16 changes: 14 additions & 2 deletions core/audits/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ const DEFAULT_PASS = 'defaultPass';
* @typedef TableOptions
* @property {number=} wastedMs
* @property {number=} wastedBytes
* @property {LH.Audit.Details.Table['sortedBy']=} sortedBy
* @property {LH.Audit.Details.Table['skipSumming']=} skipSumming
* @property {LH.Audit.Details.Table['isEntityGrouped']=} isEntityGrouped
*/

/**
* @typedef OpportunityOptions
* @property {number} overallSavingsMs
* @property {number=} overallSavingsBytes
* @property {LH.Audit.Details.Opportunity['sortedBy']=} sortedBy
* @property {LH.Audit.Details.Opportunity['skipSumming']=} skipSumming
* @property {LH.Audit.Details.Opportunity['isEntityGrouped']=} isEntityGrouped
*/

/**
Expand Down Expand Up @@ -139,7 +145,7 @@ class Audit {
* @return {LH.Audit.Details.Table}
*/
static makeTableDetails(headings, results, options = {}) {
const {wastedBytes, wastedMs} = options;
const {wastedBytes, wastedMs, sortedBy, skipSumming, isEntityGrouped} = options;
const summary = (wastedBytes || wastedMs) ? {wastedBytes, wastedMs} : undefined;
if (results.length === 0) {
return {
Expand All @@ -157,6 +163,9 @@ class Audit {
headings: headings,
items: results,
summary,
sortedBy,
skipSumming,
isEntityGrouped,
};
}

Expand Down Expand Up @@ -234,14 +243,17 @@ class Audit {
*/
static makeOpportunityDetails(headings, items, options) {
Audit.assertHeadingKeysExist(headings, items);
const {overallSavingsMs, overallSavingsBytes} = options;
const {overallSavingsMs, overallSavingsBytes, sortedBy, skipSumming, isEntityGrouped} = options;

return {
type: 'opportunity',
headings: items.length === 0 ? [] : headings,
items,
overallSavingsMs,
overallSavingsBytes,
sortedBy,
skipSumming,
isEntityGrouped,
};
}

Expand Down
5 changes: 2 additions & 3 deletions core/audits/bootup-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ class BootupTime extends Audit {
runWarnings = [str_(UIStrings.chromeExtensionsWarning)];
}

const summary = {wastedMs: totalBootupTime};

/** @type {LH.Audit.Details.Table['headings']} */
const headings = [
{key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
Expand All @@ -128,7 +126,8 @@ class BootupTime extends Audit {
label: str_(UIStrings.columnScriptParse)},
];

const details = BootupTime.makeTableDetails(headings, results, summary);
const details = BootupTime.makeTableDetails(headings, results,
{wastedMs: totalBootupTime, sortedBy: ['total']});

const score = Audit.computeLogNormalScore(
{p10: context.options.p10, median: context.options.median},
Expand Down
4 changes: 3 additions & 1 deletion core/audits/byte-efficiency/byte-efficiency-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const WASTED_MS_FOR_SCORE_OF_ZERO = 5000;
* @property {LH.IcuMessage} [displayValue]
* @property {LH.IcuMessage} [explanation]
* @property {Array<string | LH.IcuMessage>} [warnings]
* @property {Array<string>} [sortedBy]
*/

/**
Expand Down Expand Up @@ -228,8 +229,9 @@ class ByteEfficiencyAudit extends Audit {
displayValue = str_(i18n.UIStrings.displayValueByteSavings, {wastedBytes});
}

const sortedBy = result.sortedBy || ['wastedBytes'];
const details = Audit.makeOpportunityDetails(result.headings, results,
{overallSavingsMs: wastedMs, overallSavingsBytes: wastedBytes});
{overallSavingsMs: wastedMs, overallSavingsBytes: wastedBytes, sortedBy});

return {
explanation: result.explanation,
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/total-byte-weight.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class TotalByteWeight extends Audit {
{key: 'totalBytes', valueType: 'bytes', label: str_(i18n.UIStrings.columnTransferSize)},
];

const tableDetails = Audit.makeTableDetails(headings, results);
const tableDetails = Audit.makeTableDetails(headings, results, {sortedBy: ['totalBytes']});

return {
score,
Expand Down
4 changes: 2 additions & 2 deletions core/audits/byte-efficiency/uses-long-cache-ttl.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ class CacheHeaders extends Audit {
displayUnit: 'kb', granularity: 1},
];

const summary = {wastedBytes: totalWastedBytes};
const details = Audit.makeTableDetails(headings, results, summary);
const details = Audit.makeTableDetails(headings, results,
{wastedBytes: totalWastedBytes, sortedBy: ['totalBytes'], skipSumming: ['cacheLifetimeMs']});

return {
score,
Expand Down
3 changes: 2 additions & 1 deletion core/audits/long-tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ class LongTasks extends Audit {
/* eslint-enable max-len */
];

const tableDetails = Audit.makeTableDetails(headings, results);
const tableDetails = Audit.makeTableDetails(headings, results,
{sortedBy: ['duration'], skipSumming: ['startTime']});

let displayValue;
if (results.length > 0) {
Expand Down
3 changes: 2 additions & 1 deletion core/audits/mainthread-work-breakdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ class MainThreadWorkBreakdown extends Audit {
];

results.sort((a, b) => categoryTotals[b.group] - categoryTotals[a.group]);
const tableDetails = MainThreadWorkBreakdown.makeTableDetails(headings, results);
const tableDetails = MainThreadWorkBreakdown.makeTableDetails(headings, results,
{sortedBy: ['duration']});

const score = Audit.computeLogNormalScore(
{p10: context.options.p10, median: context.options.median},
Expand Down
2 changes: 1 addition & 1 deletion core/audits/network-rtt.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class NetworkRTT extends Audit {
{key: 'rtt', valueType: 'ms', granularity: 1, label: str_(i18n.UIStrings.columnTimeSpent)},
];

const tableDetails = Audit.makeTableDetails(headings, results);
const tableDetails = Audit.makeTableDetails(headings, results, {sortedBy: ['rtt']});

return {
score: 1,
Expand Down
3 changes: 2 additions & 1 deletion core/audits/network-server-latency.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class NetworkServerLatency extends Audit {
label: str_(i18n.UIStrings.columnTimeSpent)},
];

const tableDetails = Audit.makeTableDetails(headings, results);
const tableDetails = Audit.makeTableDetails(headings, results,
{sortedBy: ['serverResponseTime']});

return {
score: Math.max(1 - (maxLatency / 500), 0),
Expand Down
2 changes: 1 addition & 1 deletion core/audits/performance-budget.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class ResourceBudget extends Audit {

return {
details: Audit.makeTableDetails(headers,
this.tableItems(budget, summary)),
this.tableItems(budget, summary), {sortedBy: ['sizeOverBudget']}),
score: 1,
};
}
Expand Down
2 changes: 1 addition & 1 deletion core/audits/prioritize-lcp-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ class PrioritizeLcpImage extends Audit {
{key: 'wastedMs', valueType: 'timespanMs', label: str_(i18n.UIStrings.columnWastedMs)},
];
const details = Audit.makeOpportunityDetails(headings, results,
{overallSavingsMs: wastedMs});
{overallSavingsMs: wastedMs, sortedBy: ['wastedMs']});

// If LCP element was an image and had valid network records (regardless of
// if it should be preloaded), it will be found first in the `initiatorPath`.
Expand Down
5 changes: 4 additions & 1 deletion core/audits/third-party-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,15 @@ class ThirdPartySummary extends Audit {
};
}

const details = Audit.makeTableDetails(headings, results,
{...overallSummary, isEntityGrouped: true});

return {
score: Number(overallSummary.wastedMs <= PASS_THRESHOLD_IN_MS),
displayValue: str_(UIStrings.displayValue, {
timeInMs: overallSummary.wastedMs,
}),
details: Audit.makeTableDetails(headings, results, overallSummary),
details,
};
}
}
Expand Down
3 changes: 2 additions & 1 deletion core/audits/timing-budget.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ class TimingBudget extends Audit {
];

return {
details: Audit.makeTableDetails(headers, this.tableItems(budget, summary)),
details: Audit.makeTableDetails(headers, this.tableItems(budget, summary),
{sortedBy: ['overBudget']}),
score: 1,
};
}
Expand Down
2 changes: 1 addition & 1 deletion core/audits/uses-rel-preconnect.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class UsesRelPreconnectAudit extends Audit {
];

const details = Audit.makeOpportunityDetails(headings, results,
{overallSavingsMs: maxWasted});
{overallSavingsMs: maxWasted, sortedBy: ['wastedMs']});

return {
score: ByteEfficiencyAudit.scoreForWastedMs(maxWasted),
Expand Down
2 changes: 1 addition & 1 deletion core/audits/uses-rel-preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class UsesRelPreloadAudit extends Audit {
{key: 'wastedMs', valueType: 'timespanMs', label: str_(i18n.UIStrings.columnWastedMs)},
];
const details = Audit.makeOpportunityDetails(headings, results,
{overallSavingsMs: wastedMs});
{overallSavingsMs: wastedMs, sortedBy: ['wastedMs']});

return {
score: ByteEfficiencyAudit.scoreForWastedMs(wastedMs),
Expand Down
2 changes: 1 addition & 1 deletion core/audits/work-during-interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class WorkDuringInteraction extends Audit {
];

return {
table: Audit.makeTableDetails(headings, items),
table: Audit.makeTableDetails(headings, items, {sortedBy: ['total']}),
phases,
};
}
Expand Down
17 changes: 17 additions & 0 deletions core/lib/lighthouse-compatibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ function upgradeLhrForCompatibility(lhr) {
}
}

// In 10.0, third-party-summary deprecated entity: LinkValue and switched to entity name string
if (audit.id === 'third-party-summary') {
if (audit.details.type === 'opportunity' || audit.details.type === 'table') {
const {headings, items} = audit.details;
if (headings[0].valueType === 'link') {
// Apply upgrade only if we are dealing with an older version (valueType=link marker).
headings[0].valueType = 'text';
for (const item of items) {
if (typeof item.entity === 'object' && item.entity.type === 'link') {
item.entity = item.entity.text;
}
}
audit.details.isEntityGrouped = true;
}
}
}

// TODO: convert printf-style displayValue.
// Added: #5099, v3
// Removed: #6767, v4
Expand Down
1 change: 1 addition & 0 deletions core/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class Runner {
// Reduce payload size in LHR JSON by omitting whats falsy.
if (entity === classifiedEntities.firstParty) shortEntity.isFirstParty = true;
if (entity.isUnrecognized) shortEntity.isUnrecognized = true;
if (entity.category) shortEntity.category = entity.category;
entities.push(shortEntity);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ describe('Byte efficiency base audit', () => {
GatherContext: {gatherMode: 'timespan'},
traces: {defaultPass: trace},
devtoolsLogs: {defaultPass: []},
URL: {},
};
const computedCache = new Map();

Expand Down
1 change: 1 addition & 0 deletions core/test/audits/byte-efficiency/total-byte-weight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function generateArtifacts(records) {

return {
devtoolsLogs: {defaultPass: networkRecordsToDevtoolsLog(records)},
URL: {},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('Cache headers audit', () => {
devtoolsLogs: {
[CacheHeadersAudit.DEFAULT_PASS]: devtoolLogs,
},
URL: {},
};
}

Expand Down
8 changes: 8 additions & 0 deletions core/test/audits/work-during-interaction-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Object {
"valueType": "node",
},
],
"isEntityGrouped": undefined,
"items": Array [
Object {
"node": Object {
Expand All @@ -83,6 +84,8 @@ Object {
},
},
],
"skipSumming": undefined,
"sortedBy": undefined,
"summary": undefined,
"type": "table",
},
Expand Down Expand Up @@ -139,6 +142,7 @@ Object {
"valueType": "ms",
},
],
"isEntityGrouped": undefined,
"items": Array [
Object {
"phase": Object {
Expand Down Expand Up @@ -215,6 +219,10 @@ Object {
"total": 285,
},
],
"skipSumming": undefined,
"sortedBy": Array [
"total",
],
"summary": undefined,
"type": "table",
},
Expand Down
Loading

0 comments on commit 5aca9f3

Please sign in to comment.