Skip to content

Commit 648cce6

Browse files
authored
refactor: extract computeLogNormalScore method (#2710)
* refactor: extract computeScore method * feedback
1 parent 76cdb54 commit 648cce6

File tree

8 files changed

+64
-62
lines changed

8 files changed

+64
-62
lines changed

lighthouse-core/audits/audit.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
'use strict';
77

8+
const statistics = require('../lib/statistics');
9+
810
const DEFAULT_PASS = 'defaultPass';
911

1012
class Audit {
@@ -32,6 +34,28 @@ class Audit {
3234
throw new Error('Audit meta information must be overridden.');
3335
}
3436

37+
/**
38+
* Computes a clamped score between 0 and 100 based on the measured value. Score is determined by
39+
* considering a log-normal distribution governed by the two control points, point of diminishing
40+
* returns and the median value, and returning the percentage of sites that have higher value.
41+
*
42+
* @param {number} measuredValue
43+
* @param {number} diminishingReturnsValue
44+
* @param {number} medianValue
45+
* @return {number}
46+
*/
47+
static computeLogNormalScore(measuredValue, diminishingReturnsValue, medianValue) {
48+
const distribution = statistics.getLogNormalDistribution(
49+
medianValue,
50+
diminishingReturnsValue
51+
);
52+
53+
let score = 100 * distribution.computeComplementaryPercentile(measuredValue);
54+
score = Math.min(100, score);
55+
score = Math.max(0, score);
56+
return Math.round(score);
57+
}
58+
3559
/**
3660
* @param {!Audit} audit
3761
* @param {string} debugString

lighthouse-core/audits/byte-efficiency/total-byte-weight.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
'use strict';
1010

1111
const ByteEfficiencyAudit = require('./byte-efficiency-audit');
12-
const statistics = require('../../lib/statistics');
1312

1413
// Parameters for log-normal CDF scoring. See https://www.desmos.com/calculator/gpmjeykbwr
1514
// ~75th and ~90th percentiles http://httparchive.org/interesting.php?a=All&l=Feb%201%202017&s=All#bytesTotal
@@ -72,9 +71,11 @@ class TotalByteWeight extends ByteEfficiencyAudit {
7271
// <= 1600KB: score≈100
7372
// 4000KB: score=50
7473
// >= 9000KB: score≈0
75-
const distribution = statistics.getLogNormalDistribution(
76-
SCORING_MEDIAN, SCORING_POINT_OF_DIMINISHING_RETURNS);
77-
const score = 100 * distribution.computeComplementaryPercentile(totalBytes);
74+
const score = ByteEfficiencyAudit.computeLogNormalScore(
75+
totalBytes,
76+
SCORING_POINT_OF_DIMINISHING_RETURNS,
77+
SCORING_MEDIAN
78+
);
7879

7980
const headings = [
8081
{key: 'url', itemType: 'url', text: 'URL'},
@@ -85,10 +86,10 @@ class TotalByteWeight extends ByteEfficiencyAudit {
8586
const tableDetails = ByteEfficiencyAudit.makeTableDetails(headings, results);
8687

8788
return {
89+
score,
8890
rawValue: totalBytes,
8991
optimalValue: this.meta.optimalValue,
9092
displayValue: `Total size was ${ByteEfficiencyAudit.bytesToKbString(totalBytes)}`,
91-
score: Math.round(Math.max(0, Math.min(score, 100))),
9293
extendedInfo: {
9394
value: {
9495
results,

lighthouse-core/audits/consistently-interactive.js

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
const Audit = require('./audit');
99
const Util = require('../report/v2/renderer/util.js');
1010
const TracingProcessor = require('../lib/traces/tracing-processor');
11-
const statistics = require('../lib/statistics');
1211

1312
// Parameters (in ms) for log-normal CDF scoring. To see the curve:
1413
// https://www.desmos.com/calculator/uti67afozh
@@ -19,11 +18,6 @@ const REQUIRED_QUIET_WINDOW = 5000;
1918
const ALLOWED_CONCURRENT_REQUESTS = 2;
2019
const IGNORED_NETWORK_SCHEMES = ['data', 'ws'];
2120

22-
const distribution = statistics.getLogNormalDistribution(
23-
SCORING_MEDIAN,
24-
SCORING_POINT_OF_DIMINISHING_RETURNS
25-
);
26-
2721
/**
2822
* @fileoverview This audit identifies the time the page is "consistently interactive".
2923
* Looks for the first period of at least 5 seconds after FMP where both CPU and network were quiet,
@@ -234,14 +228,12 @@ class ConsistentlyInteractiveMetric extends Audit {
234228
const timeInMs = (timestamp - traceOfTab.timestamps.navigationStart) / 1000;
235229
const extendedInfo = Object.assign(quietPeriodInfo, {timestamp, timeInMs});
236230

237-
let score = 100 * distribution.computeComplementaryPercentile(timeInMs);
238-
// Clamp the score to 0 <= x <= 100.
239-
score = Math.min(100, score);
240-
score = Math.max(0, score);
241-
score = Math.round(score);
242-
243231
return {
244-
score,
232+
score: Audit.computeLogNormalScore(
233+
timeInMs,
234+
SCORING_POINT_OF_DIMINISHING_RETURNS,
235+
SCORING_MEDIAN
236+
),
245237
rawValue: timeInMs,
246238
displayValue: Util.formatMilliseconds(timeInMs),
247239
optimalValue: this.meta.optimalValue,

lighthouse-core/audits/dobetterweb/dom-size.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
'use strict';
1414

1515
const Audit = require('../audit');
16-
const statistics = require('../../lib/statistics');
1716
const Util = require('../../report/v2/renderer/util.js');
1817

1918
const MAX_DOM_NODES = 1500;
@@ -73,12 +72,11 @@ class DOMSize extends Audit {
7372
// <= 1500: score≈100
7473
// 3000: score=50
7574
// >= 5970: score≈0
76-
const distribution = statistics.getLogNormalDistribution(
77-
SCORING_MEDIAN, SCORING_POINT_OF_DIMINISHING_RETURNS);
78-
let score = 100 * distribution.computeComplementaryPercentile(stats.totalDOMNodes);
79-
80-
// Clamp the score to 0 <= x <= 100.
81-
score = Math.max(0, Math.min(100, score));
75+
const score = Audit.computeLogNormalScore(
76+
stats.totalDOMNodes,
77+
SCORING_POINT_OF_DIMINISHING_RETURNS,
78+
SCORING_MEDIAN
79+
);
8280

8381
const cards = [{
8482
title: 'Total DOM Nodes',
@@ -97,9 +95,9 @@ class DOMSize extends Audit {
9795
}];
9896

9997
return {
98+
score,
10099
rawValue: stats.totalDOMNodes,
101100
optimalValue: this.meta.optimalValue,
102-
score: Math.round(score),
103101
displayValue: `${Util.formatNumber(stats.totalDOMNodes)} nodes`,
104102
extendedInfo: {
105103
value: cards

lighthouse-core/audits/estimated-input-latency.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
const Audit = require('./audit');
99
const Util = require('../report/v2/renderer/util.js');
1010
const TracingProcessor = require('../lib/traces/tracing-processor');
11-
const statistics = require('../lib/statistics');
1211

1312
// Parameters (in ms) for log-normal CDF scoring. To see the curve:
1413
// https://www.desmos.com/calculator/srv0hqhf7d
@@ -51,12 +50,14 @@ class EstimatedInputLatency extends Audit {
5150
// Median = 100ms
5251
// 75th Percentile ≈ 133ms
5352
// 95th Percentile ≈ 199ms
54-
const distribution = statistics.getLogNormalDistribution(SCORING_MEDIAN,
55-
SCORING_POINT_OF_DIMINISHING_RETURNS);
56-
const score = 100 * distribution.computeComplementaryPercentile(ninetieth.time);
53+
const score = Audit.computeLogNormalScore(
54+
ninetieth.time,
55+
SCORING_POINT_OF_DIMINISHING_RETURNS,
56+
SCORING_MEDIAN
57+
);
5758

5859
return {
59-
score: Math.round(score),
60+
score,
6061
optimalValue: EstimatedInputLatency.meta.optimalValue,
6162
rawValue,
6263
displayValue: Util.formatMilliseconds(rawValue, 1),

lighthouse-core/audits/first-interactive.js

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,12 @@
77

88
const Audit = require('./audit');
99
const Util = require('../report/v2/renderer/util.js');
10-
const statistics = require('../lib/statistics');
1110

1211
// Parameters (in ms) for log-normal CDF scoring. To see the curve:
1312
// https://www.desmos.com/calculator/rjp0lbit8y
1413
const SCORING_POINT_OF_DIMINISHING_RETURNS = 1700;
1514
const SCORING_MEDIAN = 10000;
1615

17-
const distribution = statistics.getLogNormalDistribution(
18-
SCORING_MEDIAN,
19-
SCORING_POINT_OF_DIMINISHING_RETURNS
20-
);
21-
2216
class FirstInteractiveMetric extends Audit {
2317
/**
2418
* @return {!AuditMeta}
@@ -46,14 +40,12 @@ class FirstInteractiveMetric extends Audit {
4640
const trace = artifacts.traces[Audit.DEFAULT_PASS];
4741
return artifacts.requestFirstInteractive(trace)
4842
.then(firstInteractive => {
49-
let score = 100 * distribution.computeComplementaryPercentile(firstInteractive.timeInMs);
50-
// Clamp the score to 0 <= x <= 100.
51-
score = Math.min(100, score);
52-
score = Math.max(0, score);
53-
score = Math.round(score);
54-
5543
return {
56-
score,
44+
score: Audit.computeLogNormalScore(
45+
firstInteractive.timeInMs,
46+
SCORING_POINT_OF_DIMINISHING_RETURNS,
47+
SCORING_MEDIAN
48+
),
5749
rawValue: firstInteractive.timeInMs,
5850
displayValue: Util.formatMilliseconds(firstInteractive.timeInMs),
5951
extendedInfo: {

lighthouse-core/audits/first-meaningful-paint.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
const Audit = require('./audit');
99
const Util = require('../report/v2/renderer/util.js');
10-
const statistics = require('../lib/statistics');
1110

1211
// Parameters (in ms) for log-normal CDF scoring. To see the curve:
1312
// https://www.desmos.com/calculator/joz3pqttdq
@@ -101,17 +100,15 @@ class FirstMeaningfulPaint extends Audit {
101100
// 4000ms: score=50
102101
// >= 14000ms: score≈0
103102
const firstMeaningfulPaint = traceOfTab.timings.firstMeaningfulPaint;
104-
const distribution = statistics.getLogNormalDistribution(SCORING_MEDIAN,
105-
SCORING_POINT_OF_DIMINISHING_RETURNS);
106-
let score = 100 * distribution.computeComplementaryPercentile(firstMeaningfulPaint);
107-
108-
// Clamp the score to 0 <= x <= 100.
109-
score = Math.min(100, score);
110-
score = Math.max(0, score);
103+
const score = Audit.computeLogNormalScore(
104+
firstMeaningfulPaint,
105+
SCORING_POINT_OF_DIMINISHING_RETURNS,
106+
SCORING_MEDIAN
107+
);
111108

112109
return {
110+
score,
113111
duration: firstMeaningfulPaint.toFixed(1),
114-
score: Math.round(score),
115112
rawValue: firstMeaningfulPaint,
116113
extendedInfo
117114
};

lighthouse-core/audits/speed-index-metric.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
'use strict';
77

88
const Audit = require('./audit');
9-
const statistics = require('../lib/statistics');
109
const Util = require('../report/v2/renderer/util');
1110

1211
// Parameters (in ms) for log-normal CDF scoring. To see the curve:
@@ -63,13 +62,11 @@ class SpeedIndexMetric extends Audit {
6362
// Median = 5,500
6463
// 75th Percentile = 8,820
6564
// 95th Percentile = 17,400
66-
const distribution = statistics.getLogNormalDistribution(SCORING_MEDIAN,
67-
SCORING_POINT_OF_DIMINISHING_RETURNS);
68-
let score = 100 * distribution.computeComplementaryPercentile(speedline.perceptualSpeedIndex);
69-
70-
// Clamp the score to 0 <= x <= 100.
71-
score = Math.min(100, score);
72-
score = Math.max(0, score);
65+
const score = Audit.computeLogNormalScore(
66+
speedline.perceptualSpeedIndex,
67+
SCORING_POINT_OF_DIMINISHING_RETURNS,
68+
SCORING_MEDIAN
69+
);
7370

7471
const extendedInfo = {
7572
timings: {
@@ -97,7 +94,7 @@ class SpeedIndexMetric extends Audit {
9794
const rawValue = Math.round(speedline.perceptualSpeedIndex);
9895

9996
return {
100-
score: Math.round(score),
97+
score,
10198
rawValue,
10299
displayValue: Util.formatNumber(rawValue),
103100
optimalValue: this.meta.optimalValue,

0 commit comments

Comments
 (0)