Skip to content

Commit

Permalink
core(lightwallet): add timing-budget audit (#9901)
Browse files Browse the repository at this point in the history
  • Loading branch information
khempenius authored and brendankenny committed Nov 5, 2019
1 parent 14d62c2 commit 5f2b73e
Show file tree
Hide file tree
Showing 58 changed files with 405 additions and 301 deletions.
4 changes: 1 addition & 3 deletions lighthouse-core/audits/performance-budget.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ const UIStrings = {
=1 {1 request}
other {# requests}
}`,
/** Label for a column in a data table; entries will be how much the quantity or size of network requests exceeded a predetermined budget.*/
columnOverBudget: 'Over Budget',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
Expand Down Expand Up @@ -139,7 +137,7 @@ class ResourceBudget extends Audit {
{key: 'requestCount', itemType: 'numeric', text: str_(i18n.UIStrings.columnRequests)},
{key: 'size', itemType: 'bytes', text: str_(i18n.UIStrings.columnTransferSize)},
{key: 'countOverBudget', itemType: 'text', text: ''},
{key: 'sizeOverBudget', itemType: 'bytes', text: str_(UIStrings.columnOverBudget)},
{key: 'sizeOverBudget', itemType: 'bytes', text: str_(i18n.UIStrings.columnOverBudget)},
];

return {
Expand Down
146 changes: 146 additions & 0 deletions lighthouse-core/audits/timing-budget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* @license Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

const Audit = require('./audit.js');
const TimingSummary = require('../computed/metrics/timing-summary.js');
const MainResource = require('../computed/main-resource.js');
const Budget = require('../config/budget.js');
const i18n = require('../lib/i18n/i18n.js');

const UIStrings = {
/** Title of a Lighthouse audit that compares how quickly the page loads against targets set by the user. Timing budgets are a type of performance budget. */
title: 'Timing budget',
/** Description of a Lighthouse audit where a user sets budgets for how quickly the page loads. No character length limits. 'Learn More' becomes link text to additional documentation. */
description: 'Set a timing budget to help you keep an eye on the performance of your site. Performant sites load fast and respond to user input events quickly. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/budgets).',
/** Label for a column in a data table; entries will be the names of different timing metrics, e.g. "Time to Interactive", "First Contentful Paint", etc. */
columnTimingMetric: 'Metric',
/** Label for a column in a data table; entries will be the measured value of a particular timing metric. Most entries will have a unit of milliseconds, but units could be other things as well. */
columnMeasurement: 'Measurement',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

/** @typedef {{metric: LH.Budget.TimingMetric, label: string, measurement?: number, overBudget?: number}} BudgetItem */

class TimingBudget extends Audit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'timing-budget',
title: str_(UIStrings.title),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
requiredArtifacts: ['devtoolsLogs', 'traces', 'URL'],
};
}

/**
* @param {LH.Budget.TimingMetric} timingMetric
* @return {string}
*/
static getRowLabel(timingMetric) {
/** @type {Record<LH.Budget.TimingMetric, string>} */
const strMappings = {
'first-contentful-paint': i18n.UIStrings.firstContentfulPaintMetric,
'first-cpu-idle': i18n.UIStrings.firstCPUIdleMetric,
'interactive': i18n.UIStrings.interactiveMetric,
'first-meaningful-paint': i18n.UIStrings.firstMeaningfulPaintMetric,
'max-potential-fid': i18n.UIStrings.maxPotentialFIDMetric,
'estimated-input-latency': i18n.UIStrings.estimatedInputLatencyMetric,
'total-blocking-time': i18n.UIStrings.totalBlockingTimeMetric,
'speed-index': i18n.UIStrings.speedIndexMetric,
};
return str_(strMappings[timingMetric]);
}

/**
* @param {LH.Budget.TimingMetric} timingMetric
* @param {LH.Artifacts.TimingSummary} summary
* @return {number|undefined}
*/
static getMeasurement(timingMetric, summary) {
/** @type {Record<LH.Budget.TimingMetric, number|undefined>} */
const measurements = {
'first-contentful-paint': summary.firstContentfulPaint,
'first-cpu-idle': summary.firstCPUIdle,
'interactive': summary.interactive,
'first-meaningful-paint': summary.firstMeaningfulPaint,
'max-potential-fid': summary.maxPotentialFID,
'estimated-input-latency': summary.estimatedInputLatency,
'total-blocking-time': summary.totalBlockingTime,
'speed-index': summary.speedIndex,
};
return measurements[timingMetric];
}

/**
* @param {LH.Budget} budget
* @param {LH.Artifacts.TimingSummary} summary
* @return {Array<BudgetItem>}
*/
static tableItems(budget, summary) {
if (!budget.timings) {
return [];
}
return budget.timings.map((timingBudget) => {
const metricName = timingBudget.metric;
const label = this.getRowLabel(metricName);
const measurement = this.getMeasurement(metricName, summary);
const overBudget = measurement && (measurement > timingBudget.budget)
? (measurement - timingBudget.budget) : undefined;
return {
metric: metricName,
label,
measurement,
overBudget,
};
}).sort((a, b) => {
return (b.overBudget || 0) - (a.overBudget || 0);
});
}

/**
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const trace = artifacts.traces[Audit.DEFAULT_PASS];
const mainResource = await MainResource.request({URL: artifacts.URL, devtoolsLog}, context);
const summary = (await TimingSummary.request({trace, devtoolsLog}, context)).metrics;
const budget = Budget.getMatchingBudget(context.settings.budgets, mainResource.url);

if (!budget) {
return {
score: 0,
notApplicable: true,
};
}

/** @type {LH.Audit.Details.Table['headings']} */
const headers = [
{key: 'label', itemType: 'text', text: str_(UIStrings.columnTimingMetric)},
/**
* Note: SpeedIndex, unlike other timing metrics, is not measured in milliseconds.
* The renderer applies the correct units to the 'measurement' and 'overBudget' columns for SpeedIndex.
*/
{key: 'measurement', itemType: 'ms', text: str_(UIStrings.columnMeasurement)},
{key: 'overBudget', itemType: 'ms', text: str_(i18n.UIStrings.columnOverBudget)},
];

return {
details: Audit.makeTableDetails(headers, this.tableItems(budget, summary)),
score: 1,
};
}
}

module.exports = TimingBudget;
module.exports.UIStrings = UIStrings;
3 changes: 3 additions & 0 deletions lighthouse-core/computed/metrics/timing-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const FirstCPUIdle = require('./first-cpu-idle.js');
const Interactive = require('./interactive.js');
const SpeedIndex = require('./speed-index.js');
const EstimatedInputLatency = require('./estimated-input-latency.js');
const MaxPotentialFID = require('./max-potential-fid.js');
const TotalBlockingTime = require('./total-blocking-time.js');
const makeComputedArtifact = require('../computed-artifact.js');

Expand Down Expand Up @@ -44,6 +45,7 @@ class TimingSummary {
const largestContentfulPaint = await requestOrUndefined(LargestContentfulPaint, metricComputationData); // eslint-disable-line max-len
const firstCPUIdle = await requestOrUndefined(FirstCPUIdle, metricComputationData);
const interactive = await requestOrUndefined(Interactive, metricComputationData);
const maxPotentialFID = await requestOrUndefined(MaxPotentialFID, metricComputationData);
const speedIndex = await requestOrUndefined(SpeedIndex, metricComputationData);
const estimatedInputLatency = await EstimatedInputLatency.request(metricComputationData, context); // eslint-disable-line max-len
const totalBlockingTime = await TotalBlockingTime.request(metricComputationData, context); // eslint-disable-line max-len
Expand All @@ -66,6 +68,7 @@ class TimingSummary {
estimatedInputLatency: estimatedInputLatency.timing,
estimatedInputLatencyTs: estimatedInputLatency.timestamp,
totalBlockingTime: totalBlockingTime.timing,
maxPotentialFID: maxPotentialFID && maxPotentialFID.timing,

// Include all timestamps of interest from trace of tab
observedNavigationStart: traceOfTab.timings.navigationStart,
Expand Down
2 changes: 2 additions & 0 deletions lighthouse-core/lib/i18n/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ const UIStrings = {
columnTransferSize: 'Transfer Size',
/** Label for a column in a data table; entries will be the names of arbitrary objects, e.g. the name of a Javascript library, or the name of a user defined timing event. */
columnName: 'Name',
/** Label for a column in a data table; entries will be how much a predetermined budget has been exeeded by. Depending on the context, this number could represent an excess in quantity or size of network requests, or, an excess in the duration of time that it takes for the page to load.*/
columnOverBudget: 'Over Budget',
/** Label for a row in a data table; entries will be the total number and byte size of all resources loaded by a web page. */
totalResourceType: 'Total',
/** Label for a row in a data table; entries will be the total number and byte size of all 'Document' resources loaded by a web page. */
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/ar-XB.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "‏‮Lighthouse‬‏ ‏‮couldn‬‏'‏‮t‬‏ ‏‮read‬‏ ‏‮the‬‏ `start_url` ‏‮from‬‏ ‏‮the‬‏ ‏‮manifest‬‏. ‏‮As‬‏ ‏‮a‬‏ ‏‮result‬‏, ‏‮the‬‏ `start_url` ‏‮was‬‏ ‏‮assumed‬‏ ‏‮to‬‏ ‏‮be‬‏ ‏‮the‬‏ ‏‮document‬‏'‏‮s‬‏ ‏‮URL‬‏. ‏‮Error‬‏ ‏‮message‬‏: '{manifestWarning}'."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "‏‮Over‬‏ ‏‮Budget‬‏"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "‏‮Keep‬‏ ‏‮the‬‏ ‏‮quantity‬‏ ‏‮and‬‏ ‏‮size‬‏ ‏‮of‬‏ ‏‮network‬‏ ‏‮requests‬‏ ‏‮under‬‏ ‏‮the‬‏ ‏‮targets‬‏ ‏‮set‬‏ ‏‮by‬‏ ‏‮the‬‏ ‏‮provided‬‏ ‏‮performance‬‏ ‏‮budget‬‏. [‏‮Learn‬‏ ‏‮more‬‏](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "‏‮Server‬‏ ‏‮response‬‏ ‏‮times‬‏ ‏‮are‬‏ ‏‮low‬‏ (‏‮TTFB‬‏)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "‏‮Duration‬‏"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "‏‮Start‬‏ ‏‮Time‬‏"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "تعذّر على Lighthouse قراءة `start_url` من البيان. ونتيجة لذلك، كان من المفترض أن يكون `start_url` هو عنوان URL للمستند. رسالة خطأ: '{manifestWarning}'."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "تجاوز الميزانية"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "يمكنك الحفاظ على كمية طلبات الشبكة وحجمها ضمن الاستهدافات المحدّدة في ميزانية الأداء المقدّمة. [مزيد من المعلومات](https://developers.google.com/web/tools/lighthouse/audits/budgets)"
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "أوقات استجابة الخادم منخفضة (TTFB)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "المدة"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "وقت البدء"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Lighthouse не можа да прочете `start_url` от манифеста. В резултат на това бе предположено, че URL адресът на документа изпълнява функцията на `start_url`. Съобщение за грешка: „{manifestWarning}“."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Надхвърля бюджета"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Поддържайте количеството и обема на мрежовите заявки под целевите стойности в посочения бюджет за ефективността. [Научете повече](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Сървърът отговаря бързо (време до първия байт)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Продължителност"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Начален час"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Lighthouse no ha pogut llegir l'atribut `start_url` del fitxer de manifest, de manera que s'ha donat per fet que `start_url` era l'URL del document. Missatge d'error: \"{manifestWarning}\"."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Per sobre del pressupost"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Manté la quantitat i la mida de les sol·licituds de xarxa ajustades als objectius establerts al pressupost de rendiment que s'ha proporcionat. [Obtén més informació](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Els temps de resposta del servidor són baixos (TTFB)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Durada"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Hora d'inici"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Nástroji Lighthouse se v manifestu nepodařilo přečíst atribut `start_url`. Proto se předpokládá, že adresou URL dokumentu je `start_url`. Chybová zpráva: {manifestWarning}"
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Nad rozpočet"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Udržujte množství a velikost síťových požadavků pod cílovými hodnotami, které udává poskytnutý rozpočet výkonu. [Další informace](https://developers.google.com/web/tools/lighthouse/audits/budgets)"
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Doby odezvy serveru jsou krátké (TTFB)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Trvání"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Čas zahájení"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Lighthouse kunne ikke læse `start_url` fra manifestet. `start_url` blev derfor betragtet som dokumentets webadresse. Fejlmeddelelse: \"{manifestWarning}\"."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Over budget"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Sørg for, at antallet af og størrelsen på netværksanmodningerne ikke overskrider målene i det angivne budget for ydeevne. [Få flere oplysninger](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Serversvartiderne er korte (TTFB, Time To First Byte)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Varighed"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Starttidspunkt"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Lighthouse konnte die `start_url` nicht im Manifest abrufen. Daher wurde angenommen, dass es sich bei der `start_url` um die URL des Dokuments handelt. Fehlermeldung: \"{manifestWarning}\"."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Über dem Budget"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Die Anzahl und Größe der Netzwerkanfragen sollten unter den Zielvorgaben des Leistungsbudgets liegen. [Weitere Informationen.](https://developers.google.com/web/tools/lighthouse/audits/budgets)"
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Serverantwortzeiten sind niedrig (TTFB)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Dauer"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Beginn"
},
Expand Down
6 changes: 0 additions & 6 deletions lighthouse-core/lib/i18n/locales/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,9 +815,6 @@
"lighthouse-core/audits/offline-start-url.js | warningCantStart": {
"message": "Το Lighthouse δεν μπόρεσε να διαβάσει το `start_url` από το μανιφέστο. Επομένως, το `start_url` θεωρήθηκε ότι είναι το URL του εγγράφου. Μήνυμα σφάλματος: '{manifestWarning}'."
},
"lighthouse-core/audits/performance-budget.js | columnOverBudget": {
"message": "Υπέρβαση προϋπολογισμού"
},
"lighthouse-core/audits/performance-budget.js | description": {
"message": "Διατηρήστε την ποσότητα και το μέγεθος των αιτημάτων δικτύου εντός των στόχων που ορίζονται από τον παρεχόμενο προϋπολογισμό απόδοσης. [Μάθετε περισσότερα](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
},
Expand Down Expand Up @@ -1070,9 +1067,6 @@
"lighthouse-core/audits/time-to-first-byte.js | title": {
"message": "Οι χρόνοι απόκρισης διακομιστή είναι χαμηλοί (TTFB)"
},
"lighthouse-core/audits/user-timings.js | columnDuration": {
"message": "Διάρκεια"
},
"lighthouse-core/audits/user-timings.js | columnStartTime": {
"message": "Ώρα έναρξης"
},
Expand Down
Loading

0 comments on commit 5f2b73e

Please sign in to comment.