Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: align performance audit score with metric savings #15447

Merged
merged 24 commits into from
Oct 4, 2023
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
8 changes: 4 additions & 4 deletions cli/test/smokehouse/test-definitions/dobetterweb.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ const expectations = {
score: 0,
},
'no-document-write': {
score: 0,
score: 0.5,
details: {
items: {
length: 3,
Expand Down Expand Up @@ -350,7 +350,7 @@ const expectations = {
},
},
'uses-passive-event-listeners': {
score: 0,
score: 0.5,
details: {
items: {
// Note: Originally this was 7 but M56 defaults document-level
Expand Down Expand Up @@ -436,7 +436,7 @@ const expectations = {
},
},
'dom-size': {
score: 1,
score: null,
numericValue: 153,
details: {
items: [
Expand Down Expand Up @@ -563,7 +563,7 @@ const expectations = {
}}},
},
'largest-contentful-paint-element': {
score: null,
score: 0,
displayValue: /\d+\xa0ms/,
details: {
items: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const expectations = {
finalDisplayedUrl: 'http://localhost:10200/perf/third-party.html',
audits: {
'third-party-facades': {
score: 0,
score: 0.5,
displayValue: '1 facade alternative available',
details: {
items: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const expectations = {
finalDisplayedUrl: 'http://localhost:10200/perf/unsized-images.html',
audits: {
'unsized-images': {
score: 0,
score: 0.5,
details: {
items: [
{
Expand Down
2 changes: 1 addition & 1 deletion cli/test/smokehouse/test-definitions/perf-fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const expectations = {
finalDisplayedUrl: 'http://localhost:10200/perf/fonts.html',
audits: {
'font-display': {
score: 0,
score: 0.5,
details: {
items: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const expectations = {
finalDisplayedUrl: 'http://localhost:10200/perf/trace-elements.html',
audits: {
'largest-contentful-paint-element': {
score: null,
score: 0,
displayValue: /\d+\xa0ms/,
details: {
items: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const expectations = {
numericValue: '>=2000',
},
'redirects': {
score: 0.29,
score: 0,
numericValue: '>=2000',
details: {
items: [
Expand Down
19 changes: 17 additions & 2 deletions core/audits/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Audit {
static get SCORING_MODES() {
return {
NUMERIC: 'numeric',
METRIC_SAVINGS: 'metricSavings',
BINARY: 'binary',
MANUAL: 'manual',
INFORMATIVE: 'informative',
Expand Down Expand Up @@ -321,7 +322,8 @@ class Audit {
*/
static _normalizeAuditScore(score, scoreDisplayMode, auditId) {
if (scoreDisplayMode !== Audit.SCORING_MODES.BINARY &&
scoreDisplayMode !== Audit.SCORING_MODES.NUMERIC) {
scoreDisplayMode !== Audit.SCORING_MODES.NUMERIC &&
scoreDisplayMode !== Audit.SCORING_MODES.METRIC_SAVINGS) {
return null;
}

Expand Down Expand Up @@ -363,6 +365,7 @@ class Audit {

// Default to binary scoring.
let scoreDisplayMode = audit.meta.scoreDisplayMode || Audit.SCORING_MODES.BINARY;
let score = product.score;

// But override if product contents require it.
if (product.errorMessage !== undefined) {
Expand All @@ -371,9 +374,21 @@ class Audit {
} else if (product.notApplicable) {
// Audit was determined to not apply to the page.
scoreDisplayMode = Audit.SCORING_MODES.NOT_APPLICABLE;
} else if (product.scoreDisplayMode) {
scoreDisplayMode = product.scoreDisplayMode;
}

const score = Audit._normalizeAuditScore(product.score, scoreDisplayMode, audit.meta.id);
if (scoreDisplayMode === Audit.SCORING_MODES.METRIC_SAVINGS) {
if (score && score >= Util.PASS_THRESHOLD) {
score = 1;
} else if (Object.values(product.metricSavings || {}).some(v => v)) {
score = 0;
} else {
score = 0.5;
}
}

score = Audit._normalizeAuditScore(score, scoreDisplayMode, audit.meta.id);

let auditTitle = audit.meta.title;
if (audit.meta.failureTitle) {
Expand Down
1 change: 1 addition & 0 deletions core/audits/bf-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class BFCache extends Audit {
supportedModes: ['navigation', 'timespan'],
guidanceLevel: 2,
requiredArtifacts: ['BFCacheFailures'],
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
};
}

Expand Down
5 changes: 4 additions & 1 deletion core/audits/bootup-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {MainThreadTasks} from '../computed/main-thread-tasks.js';
import {getExecutionTimingsByURL} from '../lib/tracehouse/task-summary.js';
import {TBTImpactTasks} from '../computed/tbt-impact-tasks.js';
import {Sentry} from '../lib/sentry.js';
import {Util} from '../../shared/util.js';

const UIStrings = {
/** Title of a diagnostic audit that provides detail on the time spent executing javascript files during the load. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
Expand Down Expand Up @@ -47,7 +48,7 @@ class BootupTime extends Audit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 1,
requiredArtifacts: ['traces', 'devtoolsLogs', 'URL', 'GatherContext'],
};
Expand Down Expand Up @@ -169,6 +170,8 @@ class BootupTime extends Audit {

return {
score,
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
notApplicable: !results.length,
numericValue: totalBootupTime,
numericUnit: 'millisecond',
displayValue: totalBootupTime > 0 ?
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/byte-efficiency-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ class ByteEfficiencyAudit extends Audit {
displayValue,
numericValue: wastedMs,
numericUnit: 'millisecond',
score: ByteEfficiencyAudit.scoreForWastedMs(wastedMs),
score: results.length ? 0 : 1,
details,
metricSavings,
};
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/duplicated-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class DuplicatedJavascript extends ByteEfficiencyAudit {
id: 'duplicated-javascript',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 2,
requiredArtifacts: ['devtoolsLogs', 'traces', 'SourceMaps', 'Scripts',
'GatherContext', 'URL'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class EfficientAnimatedContent extends ByteEfficiencyAudit {
id: 'efficient-animated-content',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['devtoolsLogs', 'traces', 'GatherContext', 'URL'],
};
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/legacy-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
static get meta() {
return {
id: 'legacy-javascript',
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
description: str_(UIStrings.description),
title: str_(UIStrings.title),
guidanceLevel: 2,
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/modern-image-formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ModernImageFormats extends ByteEfficiencyAudit {
id: 'modern-image-formats',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['OptimizedImages', 'devtoolsLogs', 'traces', 'URL', 'GatherContext',
'ImageElements'],
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/offscreen-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OffscreenImages extends ByteEfficiencyAudit {
id: 'offscreen-images',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
supportedModes: ['navigation'],
guidanceLevel: 2,
requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext', 'devtoolsLogs',
Expand Down
5 changes: 2 additions & 3 deletions core/audits/byte-efficiency/render-blocking-resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import {Audit} from '../audit.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {BaseNode} from '../../lib/dependency-graph/base-node.js';
import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
import {UnusedCSS} from '../../computed/unused-css.js';
import {NetworkRequest} from '../../lib/network-request.js';
import {ProcessedNavigation} from '../../computed/processed-navigation.js';
Expand Down Expand Up @@ -113,7 +112,7 @@ class RenderBlockingResources extends Audit {
id: 'render-blocking-resources',
title: str_(UIStrings.title),
supportedModes: ['navigation'],
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
description: str_(UIStrings.description),
guidanceLevel: 2,
// TODO: look into adding an `optionalArtifacts` property that captures the non-required nature
Expand Down Expand Up @@ -296,7 +295,7 @@ class RenderBlockingResources extends Audit {

return {
displayValue,
score: ByteEfficiencyAudit.scoreForWastedMs(wastedMs),
score: results.length ? 0 : 1,
numericValue: wastedMs,
numericUnit: 'millisecond',
details,
Expand Down
4 changes: 3 additions & 1 deletion core/audits/byte-efficiency/total-byte-weight.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Audit} from '../audit.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {NetworkRequest} from '../../lib/network-request.js';
import {NetworkRecords} from '../../computed/network-records.js';
import {Util} from '../../../shared/util.js';

const UIStrings = {
/** Title of a diagnostic audit that provides detail on large network resources required during page load. 'Payloads' is roughly equivalent to 'resources'. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
Expand All @@ -34,7 +35,7 @@ class TotalByteWeight extends Audit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 1,
requiredArtifacts: ['devtoolsLogs'],
};
Expand Down Expand Up @@ -98,6 +99,7 @@ class TotalByteWeight extends Audit {

return {
score,
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
numericValue: totalBytes,
numericUnit: 'byte',
displayValue: str_(UIStrings.displayValue, {totalBytes}),
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/unminified-css.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit {
id: 'unminified-css',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL', 'GatherContext'],
};
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/unminified-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class UnminifiedJavaScript extends ByteEfficiencyAudit {
id: 'unminified-javascript',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['Scripts', 'devtoolsLogs', 'traces', 'GatherContext', 'URL'],
};
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/unused-css-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class UnusedCSSRules extends ByteEfficiencyAudit {
id: 'unused-css-rules',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 2,
requiredArtifacts: ['CSSUsage', 'URL', 'devtoolsLogs', 'traces', 'GatherContext'],
};
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/unused-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class UnusedJavaScript extends ByteEfficiencyAudit {
id: 'unused-javascript',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 2,
requiredArtifacts: ['JsUsage', 'Scripts', 'SourceMaps', 'GatherContext',
'devtoolsLogs', 'traces', 'URL'],
Expand Down
9 changes: 2 additions & 7 deletions core/audits/byte-efficiency/uses-long-cache-ttl.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class CacheHeaders extends Audit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['devtoolsLogs'],
};
Expand Down Expand Up @@ -266,11 +266,6 @@ class CacheHeaders extends Audit {
a.url.localeCompare(b.url);
});

const score = Audit.computeLogNormalScore(
{p10: context.options.p10, median: context.options.median},
totalWastedBytes
);

/** @type {LH.Audit.Details.Table['headings']} */
const headings = [
{key: 'url', valueType: 'url', label: str_(i18n.UIStrings.columnURL)},
Expand All @@ -285,7 +280,7 @@ class CacheHeaders extends Audit {
{wastedBytes: totalWastedBytes, sortedBy: ['totalBytes'], skipSumming: ['cacheLifetimeMs']});

return {
score,
score: results.length ? 0 : 1,
numericValue: totalWastedBytes,
numericUnit: 'byte',
displayValue: str_(UIStrings.displayValue, {itemCount: results.length}),
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/uses-optimized-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit {
id: 'uses-optimized-images',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 2,
requiredArtifacts: ['OptimizedImages', 'ImageElements', 'GatherContext', 'devtoolsLogs',
'traces', 'URL'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class UsesResponsiveImagesSnapshot extends Audit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: UsesResponsiveImages.str_(UsesResponsiveImages.UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
supportedModes: ['snapshot'],
guidanceLevel: 2,
requiredArtifacts: ['ImageElements', 'ViewportDimensions'],
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/uses-responsive-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class UsesResponsiveImages extends ByteEfficiencyAudit {
id: 'uses-responsive-images',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 2,
requiredArtifacts: ['ImageElements', 'ViewportDimensions', 'GatherContext',
'devtoolsLogs', 'traces', 'URL'],
Expand Down
2 changes: 1 addition & 1 deletion core/audits/byte-efficiency/uses-text-compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit {
id: 'uses-text-compression',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC,
scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 3,
requiredArtifacts: ['ResponseCompression', 'GatherContext', 'devtoolsLogs', 'traces', 'URL'],
};
Expand Down
4 changes: 3 additions & 1 deletion core/audits/dobetterweb/dom-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import {Audit} from '../audit.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {TBTImpactTasks} from '../../computed/tbt-impact-tasks.js';
import {Util} from '../../../shared/util.js';

const UIStrings = {
/** Title of a diagnostic audit that provides detail on the size of the web page's DOM. The size of a DOM is characterized by the total number of DOM elements and greatest DOM depth. This descriptive title is shown to users when the amount is acceptable and no user action is required. */
Expand Down Expand Up @@ -53,7 +54,7 @@ class DOMSize extends Audit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
scoreDisplayMode: Audit.SCORING_MODES.METRIC_SAVINGS,
guidanceLevel: 1,
requiredArtifacts: ['DOMStats', 'URL', 'GatherContext'],
__internalOptionalArtifacts: ['traces', 'devtoolsLogs'],
Expand Down Expand Up @@ -167,6 +168,7 @@ class DOMSize extends Audit {

return {
score,
scoreDisplayMode: score >= Util.PASS_THRESHOLD ? Audit.SCORING_MODES.INFORMATIVE : undefined,
numericValue: stats.totalBodyElements,
numericUnit: 'element',
displayValue: str_(UIStrings.displayValue, {itemCount: stats.totalBodyElements}),
Expand Down
Loading
Loading