From 51d7a40bc2033a0957e11d13a259eea078e6a326 Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Sun, 28 Apr 2019 14:33:12 -0400 Subject: [PATCH 1/6] Add resource-summary audit --- lighthouse-core/audits/resource-summary.js | 114 +++++++++++++++ lighthouse-core/config/default-config.js | 2 + lighthouse-core/lib/i18n/en-US.json | 104 +++++++++++++ .../test/audits/resource-summary-test.js | 54 +++++++ lighthouse-core/test/results/sample_v2.json | 137 ++++++++++++++++++ types/budget.d.ts | 2 +- 6 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 lighthouse-core/audits/resource-summary.js create mode 100644 lighthouse-core/test/audits/resource-summary-test.js diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js new file mode 100644 index 000000000000..61e8f8ba62c0 --- /dev/null +++ b/lighthouse-core/audits/resource-summary.js @@ -0,0 +1,114 @@ +/** + * @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 NetworkRecords = require('../computed/network-records.js'); +const ComputedResourceSummary = require('../computed/resource-summary.js'); +const i18n = require('../lib/i18n/i18n.js'); +const MainResource = require('../computed/main-resource.js'); + +const UIStrings = { + /** Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page. */ + title: 'Keep request counts and transfer sizes small', + /** Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. */ + description: 'To set budgets for the quantity and size of page resources,' + + ' add a budget.json file.', + /** [ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page. */ + displayValue: `{requestCount, plural, =1 {1 request} other {# requests}}` + + ` • { byteCount, number, bytes } KB`, + /** 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. */ + documentResourceType: 'Document', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. */ + scriptResourceType: 'Script', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. */ + stylesheetResourceType: 'Stylesheet', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page */ + imageResourceType: 'Image', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page */ + mediaResourceType: 'Media', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page */ + fontResourceType: 'Font', + /** 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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font.*/ + otherResourceType: 'Other', + /** Label for a row in a data table; entries will be the total number and byte size of all third-part resources loaded by a web page */ + thirdPartyResourceType: 'Third-party', +}; + +const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + +class ResourceSummary extends Audit { + /** + * @return {LH.Audit.Meta} + */ + static get meta() { + return { + id: 'resource-summary', + title: str_(UIStrings.title), + description: str_(UIStrings.description), + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, + requiredArtifacts: ['devtoolsLogs'], + }; + } + + /** + * @param {LH.Artifacts} artifacts + * @param {LH.Audit.Context} context + * @return {Promise} + */ + static async audit(artifacts, context) { + const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS]; + const networkRecords = await NetworkRecords.request(devtoolsLog, context); + const mainResource = await (MainResource.request({devtoolsLog, URL: artifacts.URL}, context)); + const resourceSummary = ComputedResourceSummary.summarize(networkRecords, mainResource.url); + + /** @type {LH.Audit.Details.Table['headings']} */ + const headings = [ + {key: 'label', itemType: 'text', text: 'Resource Type'}, + {key: 'count', itemType: 'numeric', text: 'Requests'}, + {key: 'size', itemType: 'bytes', text: 'Transfer Size'}, + ]; + + /** @type {Record} */ + const strMappings = { + total: str_(UIStrings.totalResourceType), + document: str_(UIStrings.documentResourceType), + script: str_(UIStrings.scriptResourceType), + stylesheet: str_(UIStrings.stylesheetResourceType), + image: str_(UIStrings.imageResourceType), + media: str_(UIStrings.mediaResourceType), + font: str_(UIStrings.fontResourceType), + other: str_(UIStrings.otherResourceType), + 'third-party': str_(UIStrings.thirdPartyResourceType), + }; + + const tableContents = Object.keys(resourceSummary).map((type) => { + return { + label: strMappings[type], + count: resourceSummary[type].count, + size: resourceSummary[type].size, + }; + }).sort((a, b) => { + return b.size - a.size; + }); + + const tableDetails = Audit.makeTableDetails(headings, tableContents); + + return { + details: tableDetails, + score: 1, + displayValue: str_(UIStrings.displayValue, { + requestCount: resourceSummary.total.count, + byteCount: resourceSummary.total.size, + }), + }; + } +} + +module.exports = ResourceSummary; +module.exports.UIStrings = UIStrings; diff --git a/lighthouse-core/config/default-config.js b/lighthouse-core/config/default-config.js index 48951810ba07..5cd33e467d78 100644 --- a/lighthouse-core/config/default-config.js +++ b/lighthouse-core/config/default-config.js @@ -192,6 +192,7 @@ const defaultConfig = { 'main-thread-tasks', 'metrics', 'offline-start-url', + 'resource-summary', 'manual/pwa-cross-browser', 'manual/pwa-page-transitions', 'manual/pwa-each-page-has-url', @@ -378,6 +379,7 @@ const defaultConfig = { {id: 'bootup-time', weight: 0, group: 'diagnostics'}, {id: 'mainthread-work-breakdown', weight: 0, group: 'diagnostics'}, {id: 'font-display', weight: 0, group: 'diagnostics'}, + {id: 'resource-summary', weight: 0, group: 'diagnostics'}, // Audits past this point don't belong to a group and will not be shown automatically {id: 'network-requests', weight: 0}, {id: 'network-rtt', weight: 0}, diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 3c37fd85c737..2d78c523f8fc 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -751,6 +751,102 @@ "message": "Avoid multiple page redirects", "description": "Imperative title of a Lighthouse audit that tells the user to eliminate the redirects taken through multiple URLs to load the page. This is shown in a list of audits that Lighthouse generates." }, + "lighthouse-core/audits/resource-budget.js | description": { + "message": "To set budgets for the quantity and size of page resources, add a budget.json file.", + "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits." + }, + "lighthouse-core/audits/resource-budget.js | documentResourceType": { + "message": "Document", + "description": "Label for the 'Document' resource type." + }, + "lighthouse-core/audits/resource-budget.js | fontResourceType": { + "message": "Font", + "description": "Label for the 'font' resource type." + }, + "lighthouse-core/audits/resource-budget.js | imageResourceType": { + "message": "Image", + "description": "Label for the 'image' resource type." + }, + "lighthouse-core/audits/resource-budget.js | mediaResourceType": { + "message": "Media", + "description": "Label for the 'media' resource type." + }, + "lighthouse-core/audits/resource-budget.js | otherResourceType": { + "message": "Other", + "description": "Label for the 'other' resource type." + }, + "lighthouse-core/audits/resource-budget.js | requestCount": { + "message": "{count, plural,\n =1 {1 request}\n other {# requests}\n }", + "description": "[ICU Syntax] Label identifying the number of requests" + }, + "lighthouse-core/audits/resource-budget.js | scriptResourceType": { + "message": "Script", + "description": "Label for the 'script' resource type." + }, + "lighthouse-core/audits/resource-budget.js | stylesheetResourceType": { + "message": "Stylesheet", + "description": "Label for the 'stylesheet' resource type." + }, + "lighthouse-core/audits/resource-budget.js | thirdPartyResourceType": { + "message": "Third-party", + "description": "Label for the 'third-party' resource type." + }, + "lighthouse-core/audits/resource-budget.js | title": { + "message": "Keep request counts and file sizes small", + "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." + }, + "lighthouse-core/audits/resource-budget.js | totalResourceType": { + "message": "Total", + "description": "" + }, + "lighthouse-core/audits/resource-summary.js | description": { + "message": "To set budgets for the quantity and size of page resources, add a budgets.json file.", + "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits." + }, + "lighthouse-core/audits/resource-summary.js | displayValue": { + "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB", + "description": "[ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page." + }, + "lighthouse-core/audits/resource-summary.js | documentResourceType": { + "message": "Document", + "description": "Label for the 'Document' resource type." + }, + "lighthouse-core/audits/resource-summary.js | fontResourceType": { + "message": "Font", + "description": "Label for the 'font' resource type." + }, + "lighthouse-core/audits/resource-summary.js | imageResourceType": { + "message": "Image", + "description": "Label for the 'image' resource type." + }, + "lighthouse-core/audits/resource-summary.js | mediaResourceType": { + "message": "Media", + "description": "Label for the 'media' resource type." + }, + "lighthouse-core/audits/resource-summary.js | otherResourceType": { + "message": "Other", + "description": "Label for the 'other' resource type." + }, + "lighthouse-core/audits/resource-summary.js | scriptResourceType": { + "message": "Script", + "description": "Label for the 'script' resource type." + }, + "lighthouse-core/audits/resource-summary.js | stylesheetResourceType": { + "message": "Stylesheet", + "description": "Label for the 'stylesheet' resource type." + }, + "lighthouse-core/audits/resource-summary.js | thirdPartyResourceType": { + "message": "Third-party", + "description": "Label for the 'third-party' resource type." + }, + "lighthouse-core/audits/resource-summary.js | title": { + "message": "Keep request counts and file sizes small", + "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." + }, + "lighthouse-core/audits/resource-summary.js | totalResourceType": { + "message": "Total", + "description": "Label for the combination of all resources on the page." + }, "lighthouse-core/audits/seo/canonical.js | description": { "message": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).", "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." @@ -1103,6 +1199,14 @@ "message": "Tables and lists", "description": "Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology." }, + "lighthouse-core/config/default-config.js | budgetsGroupDescription": { + "message": "Performance budgets set standards for the performance of your site.", + "description": "Description of the Budgets section of the Performance category. Within this section the budget results are displayed." + }, + "lighthouse-core/config/default-config.js | budgetsGroupTitle": { + "message": "Budgets", + "description": "Title of the Budgets section of the Performance Category. 'Budgets' refers to a budget (like a financial budget), but applied to the amount of resources on a page, rather than money." + }, "lighthouse-core/config/default-config.js | diagnosticsGroupDescription": { "message": "More information about the performance of your application.", "description": "Description of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on the page's page load performance characteristics. Whereas the 'Opportunities' suggest an action along with expected time savings, diagnostics do not. Within this section, the user may read the details and deduce additional actions they could take." diff --git a/lighthouse-core/test/audits/resource-summary-test.js b/lighthouse-core/test/audits/resource-summary-test.js new file mode 100644 index 000000000000..af84c4138903 --- /dev/null +++ b/lighthouse-core/test/audits/resource-summary-test.js @@ -0,0 +1,54 @@ +/** + * @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 ResourceSummaryAudit = require('../../audits/resource-summary.js'); +const assert = require('assert'); +const networkRecordsToDevtoolsLog = require('../network-records-to-devtools-log.js'); + +/* eslint-env jest */ + +describe('Performance: Resource summary audit', () => { + let artifacts; + let context; + beforeEach(() => { + context = {computedCache: new Map()}; + + artifacts = { + devtoolsLogs: { + defaultPass: networkRecordsToDevtoolsLog([ + {url: 'http://example.com/file.html', resourceType: 'Document', transferSize: 30}, + {url: 'http://example.com/app.js', resourceType: 'Script', transferSize: 10}, + {url: 'http://third-party.com/script.js', resourceType: 'Script', transferSize: 50}, + {url: 'http://third-party.com/file.jpg', resourceType: 'Image', transferSize: 70}, + ])}, + URL: { requestedUrl: 'https://example.com', finalUrl: 'https://example.com' }, + }; + }); + + it('includes all resource types, regardless of whether page contains them', () => { + return ResourceSummaryAudit.audit(artifacts, context).then(result => { + assert.equal(Object.keys(result.details.items).length, 9); + }); + }); + + it('it displays "0" if there are no resources of that type', () => { + return ResourceSummaryAudit.audit(artifacts, context).then(result => { + const fontItem = result.details.items.find(item => item.resourceType === 'font'); + assert.equal(fontItem.count, 0); + assert.equal(fontItem.size, 0); + }); + }); + + it('it sorts items by size (descending)', () => { + return ResourceSummaryAudit.audit(artifacts, context).then(result => { + const items = result.details.items; + assert.ok(items[0].size >= items[1].size); + assert.ok(items[1].size >= items[2].size); + assert.ok(items[2].size >= items[3].size); + }); + }); +}); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index a413fe98da15..37d63049f1e6 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -1273,6 +1273,90 @@ "explanation": "No usable web app manifest found on page.", "warnings": [] }, + "resource-summary": { + "id": "resource-summary", + "title": "Keep request counts and file sizes small", + "description": "To set budgets for the quantity and size of page resources, add a budget.json file.", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "18 requests • 157 KB", + "details": { + "type": "table", + "headings": [ + { + "key": "label", + "itemType": "text", + "text": "Resource Type" + }, + { + "key": "count", + "itemType": "numeric", + "text": "Requests" + }, + { + "key": "size", + "itemType": "bytes", + "text": "File Size" + } + ], + "items": [ + { + "resourceType": "total", + "label": "Total", + "count": 18, + "size": 160738 + }, + { + "resourceType": "script", + "label": "Script", + "count": 4, + "size": 103675 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "count": 2, + "size": 30174 + }, + { + "resourceType": "image", + "label": "Image", + "count": 2, + "size": 24741 + }, + { + "resourceType": "document", + "label": "Document", + "count": 3, + "size": 14109 + }, + { + "resourceType": "other", + "label": "Other", + "count": 2, + "size": 12861 + }, + { + "resourceType": "stylesheet", + "label": "Stylesheet", + "count": 7, + "size": 5352 + }, + { + "resourceType": "media", + "label": "Media", + "count": 0, + "size": 0 + }, + { + "resourceType": "font", + "label": "Font", + "count": 0, + "size": 0 + } + ] + } + }, "pwa-cross-browser": { "id": "pwa-cross-browser", "title": "Site works cross-browser", @@ -3120,6 +3204,11 @@ "weight": 0, "group": "diagnostics" }, + { + "id": "resource-summary", + "weight": 0, + "group": "diagnostics" + }, { "id": "network-requests", "weight": 0 @@ -4087,6 +4176,12 @@ "duration": 100, "entryType": "measure" }, + { + "startTime": 0, + "name": "lh:audit:resource-summary", + "duration": 100, + "entryType": "measure" + }, { "startTime": 0, "name": "lh:audit:pwa-cross-browser", @@ -4862,6 +4957,48 @@ "lighthouse-core/audits/network-server-latency.js | description": [ "audits[network-server-latency].description" ], + "lighthouse-core/audits/resource-summary.js | title": [ + "audits[resource-summary].title" + ], + "lighthouse-core/audits/resource-summary.js | description": [ + "audits[resource-summary].description" + ], + "lighthouse-core/audits/resource-summary.js | displayValue": [ + { + "values": { + "requestCount": 18, + "byteCount": 160738 + }, + "path": "audits[resource-summary].displayValue" + } + ], + "lighthouse-core/audits/resource-summary.js | totalResourceType": [ + "audits[resource-summary].details.items[0].label" + ], + "lighthouse-core/audits/resource-summary.js | scriptResourceType": [ + "audits[resource-summary].details.items[1].label" + ], + "lighthouse-core/audits/resource-summary.js | thirdPartyResourceType": [ + "audits[resource-summary].details.items[2].label" + ], + "lighthouse-core/audits/resource-summary.js | imageResourceType": [ + "audits[resource-summary].details.items[3].label" + ], + "lighthouse-core/audits/resource-summary.js | documentResourceType": [ + "audits[resource-summary].details.items[4].label" + ], + "lighthouse-core/audits/resource-summary.js | otherResourceType": [ + "audits[resource-summary].details.items[5].label" + ], + "lighthouse-core/audits/resource-summary.js | stylesheetResourceType": [ + "audits[resource-summary].details.items[6].label" + ], + "lighthouse-core/audits/resource-summary.js | mediaResourceType": [ + "audits[resource-summary].details.items[7].label" + ], + "lighthouse-core/audits/resource-summary.js | fontResourceType": [ + "audits[resource-summary].details.items[8].label" + ], "lighthouse-core/audits/accessibility/accesskeys.js | title": [ "audits.accesskeys.title" ], diff --git a/types/budget.d.ts b/types/budget.d.ts index b1da9e8de36c..7840164590af 100644 --- a/types/budget.d.ts +++ b/types/budget.d.ts @@ -40,7 +40,7 @@ declare global { export type TimingMetric = 'first-contentful-paint' | 'first-cpu-idle' | 'interactive' | 'first-meaningful-paint' | 'estimated-input-latency'; /** Supported resource types. */ - export type ResourceType = 'stylesheet' | 'image' | 'media' | 'font' | 'script' | 'document' | 'other'; + export type ResourceType = 'stylesheet' | 'image' | 'media' | 'font' | 'script' | 'document' | 'other' | 'total' | 'third-party'; } } } From 7ba2fb2281bb03e21beda10cef4a25095f3e6b2e Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Tue, 30 Apr 2019 15:15:26 -0400 Subject: [PATCH 2/6] lightwallet: add gray circle styling for info audits --- lighthouse-core/audits/resource-summary.js | 23 +++--- lighthouse-core/lib/i18n/en-US.json | 78 +++---------------- lighthouse-core/report/html/report-styles.css | 6 ++ .../test/audits/resource-summary-test.js | 18 ++++- 4 files changed, 48 insertions(+), 77 deletions(-) diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js index 61e8f8ba62c0..f54f0e6b3b54 100644 --- a/lighthouse-core/audits/resource-summary.js +++ b/lighthouse-core/audits/resource-summary.js @@ -74,21 +74,26 @@ class ResourceSummary extends Audit { {key: 'size', itemType: 'bytes', text: 'Transfer Size'}, ]; + /** @type {Record} */ const strMappings = { - total: str_(UIStrings.totalResourceType), - document: str_(UIStrings.documentResourceType), - script: str_(UIStrings.scriptResourceType), - stylesheet: str_(UIStrings.stylesheetResourceType), - image: str_(UIStrings.imageResourceType), - media: str_(UIStrings.mediaResourceType), - font: str_(UIStrings.fontResourceType), - other: str_(UIStrings.otherResourceType), + 'total': str_(UIStrings.totalResourceType), + 'document': str_(UIStrings.documentResourceType), + 'script': str_(UIStrings.scriptResourceType), + 'stylesheet': str_(UIStrings.stylesheetResourceType), + 'image': str_(UIStrings.imageResourceType), + 'media': str_(UIStrings.mediaResourceType), + 'font': str_(UIStrings.fontResourceType), + 'other': str_(UIStrings.otherResourceType), 'third-party': str_(UIStrings.thirdPartyResourceType), }; - const tableContents = Object.keys(resourceSummary).map((type) => { + const types = /** @type {Array} */ (Object.keys(resourceSummary)); + + const tableContents = types.map((type) => { return { + // ResourceType is included as an "id". It does not appear directly in the table. + resourceType: type, label: strMappings[type], count: resourceSummary[type].count, size: resourceSummary[type].size, diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 5c8c9e3117ee..5f0d6efa2865 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -751,56 +751,8 @@ "message": "Avoid multiple page redirects", "description": "Imperative title of a Lighthouse audit that tells the user to eliminate the redirects taken through multiple URLs to load the page. This is shown in a list of audits that Lighthouse generates." }, - "lighthouse-core/audits/resource-budget.js | description": { - "message": "To set budgets for the quantity and size of page resources, add a budget.json file.", - "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits." - }, - "lighthouse-core/audits/resource-budget.js | documentResourceType": { - "message": "Document", - "description": "Label for the 'Document' resource type." - }, - "lighthouse-core/audits/resource-budget.js | fontResourceType": { - "message": "Font", - "description": "Label for the 'font' resource type." - }, - "lighthouse-core/audits/resource-budget.js | imageResourceType": { - "message": "Image", - "description": "Label for the 'image' resource type." - }, - "lighthouse-core/audits/resource-budget.js | mediaResourceType": { - "message": "Media", - "description": "Label for the 'media' resource type." - }, - "lighthouse-core/audits/resource-budget.js | otherResourceType": { - "message": "Other", - "description": "Label for the 'other' resource type." - }, - "lighthouse-core/audits/resource-budget.js | requestCount": { - "message": "{count, plural,\n =1 {1 request}\n other {# requests}\n }", - "description": "[ICU Syntax] Label identifying the number of requests" - }, - "lighthouse-core/audits/resource-budget.js | scriptResourceType": { - "message": "Script", - "description": "Label for the 'script' resource type." - }, - "lighthouse-core/audits/resource-budget.js | stylesheetResourceType": { - "message": "Stylesheet", - "description": "Label for the 'stylesheet' resource type." - }, - "lighthouse-core/audits/resource-budget.js | thirdPartyResourceType": { - "message": "Third-party", - "description": "Label for the 'third-party' resource type." - }, - "lighthouse-core/audits/resource-budget.js | title": { - "message": "Keep request counts and file sizes small", - "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." - }, - "lighthouse-core/audits/resource-budget.js | totalResourceType": { - "message": "Total", - "description": "" - }, "lighthouse-core/audits/resource-summary.js | description": { - "message": "To set budgets for the quantity and size of page resources, add a budgets.json file.", + "message": "To set budgets for the quantity and size of page resources, add a budget.json file.", "description": "Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits." }, "lighthouse-core/audits/resource-summary.js | displayValue": { @@ -809,43 +761,43 @@ }, "lighthouse-core/audits/resource-summary.js | documentResourceType": { "message": "Document", - "description": "Label for the 'Document' resource type." + "description": "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." }, "lighthouse-core/audits/resource-summary.js | fontResourceType": { "message": "Font", - "description": "Label for the 'font' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page" }, "lighthouse-core/audits/resource-summary.js | imageResourceType": { "message": "Image", - "description": "Label for the 'image' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page" }, "lighthouse-core/audits/resource-summary.js | mediaResourceType": { "message": "Media", - "description": "Label for the 'media' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page" }, "lighthouse-core/audits/resource-summary.js | otherResourceType": { "message": "Other", - "description": "Label for the 'other' resource type." + "description": "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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font." }, "lighthouse-core/audits/resource-summary.js | scriptResourceType": { "message": "Script", - "description": "Label for the 'script' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page." }, "lighthouse-core/audits/resource-summary.js | stylesheetResourceType": { "message": "Stylesheet", - "description": "Label for the 'stylesheet' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page." }, "lighthouse-core/audits/resource-summary.js | thirdPartyResourceType": { "message": "Third-party", - "description": "Label for the 'third-party' resource type." + "description": "Label for a row in a data table; entries will be the total number and byte size of all third-part resources loaded by a web page" }, "lighthouse-core/audits/resource-summary.js | title": { - "message": "Keep request counts and file sizes small", + "message": "Keep request counts and transfer sizes small", "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." }, "lighthouse-core/audits/resource-summary.js | totalResourceType": { "message": "Total", - "description": "Label for the combination of all resources on the page." + "description": "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." }, "lighthouse-core/audits/seo/canonical.js | description": { "message": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).", @@ -1199,14 +1151,6 @@ "message": "Tables and lists", "description": "Title of the navigation section within the Accessibility category. Within this section are audits with descriptive titles that highlight opportunities to improve the experience of reading tabular or list data using assistive technology." }, - "lighthouse-core/config/default-config.js | budgetsGroupDescription": { - "message": "Performance budgets set standards for the performance of your site.", - "description": "Description of the Budgets section of the Performance category. Within this section the budget results are displayed." - }, - "lighthouse-core/config/default-config.js | budgetsGroupTitle": { - "message": "Budgets", - "description": "Title of the Budgets section of the Performance Category. 'Budgets' refers to a budget (like a financial budget), but applied to the amount of resources on a page, rather than money." - }, "lighthouse-core/config/default-config.js | diagnosticsGroupDescription": { "message": "More information about the performance of your application.", "description": "Description of the diagnostics section of the Performance category. Within this section are audits with non-imperative titles that provide more detail on the page's page load performance characteristics. Whereas the 'Opportunities' suggest an action along with expected time savings, diagnostics do not. Within this section, the user may read the details and deduce additional actions they could take." diff --git a/lighthouse-core/report/html/report-styles.css b/lighthouse-core/report/html/report-styles.css index 7421805b3c81..0e9fefd49a7d 100644 --- a/lighthouse-core/report/html/report-styles.css +++ b/lighthouse-core/report/html/report-styles.css @@ -432,6 +432,12 @@ display: none; } +.lh-audit--informative .lh-audit__score-icon { + border: none; + border-radius: 100%; + background: var(--color-black-400); +} + .lh-audit__description, .lh-audit__stackpack { color: var(--secondary-text-color); diff --git a/lighthouse-core/test/audits/resource-summary-test.js b/lighthouse-core/test/audits/resource-summary-test.js index af84c4138903..0123fc5a98f2 100644 --- a/lighthouse-core/test/audits/resource-summary-test.js +++ b/lighthouse-core/test/audits/resource-summary-test.js @@ -25,10 +25,26 @@ describe('Performance: Resource summary audit', () => { {url: 'http://third-party.com/script.js', resourceType: 'Script', transferSize: 50}, {url: 'http://third-party.com/file.jpg', resourceType: 'Image', transferSize: 70}, ])}, - URL: { requestedUrl: 'https://example.com', finalUrl: 'https://example.com' }, + URL: {requestedUrl: 'https://example.com', finalUrl: 'https://example.com'}, }; }); + it('has three table columns', () => { + return ResourceSummaryAudit.audit(artifacts, context).then(result => { + assert.equal(result.details.headings.length, 3); + }); + }); + + it('includes the correct properties for each table item', () => { + return ResourceSummaryAudit.audit(artifacts, context).then(result => { + const item = result.details.items[0]; + assert.equal(item.resourceType, 'total'); + assert.ok(item.label); + assert.equal(item.count, 4); + assert.equal(item.size, 160); + }); + }); + it('includes all resource types, regardless of whether page contains them', () => { return ResourceSummaryAudit.audit(artifacts, context).then(result => { assert.equal(Object.keys(result.details.items).length, 9); From f8e51771e124e2adf0e1b6d85713a4f5209ace11 Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Tue, 30 Apr 2019 16:02:16 -0400 Subject: [PATCH 3/6] lightwallet: update test artifacts; mv some strings to shared --- .../test/cli/__snapshots__/index-test.js.snap | 8 + lighthouse-core/audits/resource-summary.js | 58 +++---- lighthouse-core/lib/i18n/en-US.json | 80 +++++----- lighthouse-core/lib/i18n/i18n.js | 20 +++ lighthouse-core/report/html/renderer/util.js | 3 - .../test/audits/resource-summary-test.js | 64 ++++---- lighthouse-core/test/results/sample_v2.json | 42 ++--- proto/sample_v2_round_trip.json | 146 +++++++++++++++--- types/budget.d.ts | 2 +- 9 files changed, 260 insertions(+), 163 deletions(-) diff --git a/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap index dd4636eb9237..c164f10bd5de 100644 --- a/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap +++ b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap @@ -120,6 +120,9 @@ Object { Object { "path": "offline-start-url", }, + Object { + "path": "resource-summary", + }, Object { "path": "manual/pwa-cross-browser", }, @@ -811,6 +814,11 @@ Object { "id": "font-display", "weight": 0, }, + Object { + "group": "diagnostics", + "id": "resource-summary", + "weight": 0, + }, Object { "id": "network-requests", "weight": 0, diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js index f54f0e6b3b54..665247b0681c 100644 --- a/lighthouse-core/audits/resource-summary.js +++ b/lighthouse-core/audits/resource-summary.js @@ -20,24 +20,6 @@ const UIStrings = { /** [ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page. */ displayValue: `{requestCount, plural, =1 {1 request} other {# requests}}` + ` • { byteCount, number, bytes } KB`, - /** 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. */ - documentResourceType: 'Document', - /** Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. */ - scriptResourceType: 'Script', - /** Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. */ - stylesheetResourceType: 'Stylesheet', - /** Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page */ - imageResourceType: 'Image', - /** Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page */ - mediaResourceType: 'Media', - /** Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page */ - fontResourceType: 'Font', - /** 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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font.*/ - otherResourceType: 'Other', - /** Label for a row in a data table; entries will be the total number and byte size of all third-part resources loaded by a web page */ - thirdPartyResourceType: 'Third-party', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -64,39 +46,39 @@ class ResourceSummary extends Audit { static async audit(artifacts, context) { const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS]; const networkRecords = await NetworkRecords.request(devtoolsLog, context); - const mainResource = await (MainResource.request({devtoolsLog, URL: artifacts.URL}, context)); - const resourceSummary = ComputedResourceSummary.summarize(networkRecords, mainResource.url); + const mainResource = await MainResource.request({devtoolsLog, URL: artifacts.URL}, context); + const summary = ComputedResourceSummary.summarize(networkRecords, mainResource.url); /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'label', itemType: 'text', text: 'Resource Type'}, {key: 'count', itemType: 'numeric', text: 'Requests'}, - {key: 'size', itemType: 'bytes', text: 'Transfer Size'}, + {key: 'sizpi18e', itemType: 'bytes', text: 'Transfer Size'}, ]; /** @type {Record} */ const strMappings = { - 'total': str_(UIStrings.totalResourceType), - 'document': str_(UIStrings.documentResourceType), - 'script': str_(UIStrings.scriptResourceType), - 'stylesheet': str_(UIStrings.stylesheetResourceType), - 'image': str_(UIStrings.imageResourceType), - 'media': str_(UIStrings.mediaResourceType), - 'font': str_(UIStrings.fontResourceType), - 'other': str_(UIStrings.otherResourceType), - 'third-party': str_(UIStrings.thirdPartyResourceType), + 'total': str_(i18n.UIStrings.totalResourceType), + 'document': str_(i18n.UIStrings.documentResourceType), + 'script': str_(i18n.UIStrings.scriptResourceType), + 'stylesheet': str_(i18n.UIStrings.stylesheetResourceType), + 'image': str_(i18n.UIStrings.imageResourceType), + 'media': str_(i18n.UIStrings.mediaResourceType), + 'font': str_(i18n.UIStrings.fontResourceType), + 'other': str_(i18n.UIStrings.otherResourceType), + 'third-party': str_(i18n.UIStrings.thirdPartyResourceType), }; - const types = /** @type {Array} */ (Object.keys(resourceSummary)); - - const tableContents = types.map((type) => { + const types = /** @type {Array} */ (Object.keys(summary)); + const tableContents = types.map(type => { return { - // ResourceType is included as an "id". It does not appear directly in the table. + // ResourceType is included as an "id" for ease of use. + // It does not appear directly in the table. resourceType: type, label: strMappings[type], - count: resourceSummary[type].count, - size: resourceSummary[type].size, + count: summary[type].count, + size: summary[type].size, }; }).sort((a, b) => { return b.size - a.size; @@ -108,8 +90,8 @@ class ResourceSummary extends Audit { details: tableDetails, score: 1, displayValue: str_(UIStrings.displayValue, { - requestCount: resourceSummary.total.count, - byteCount: resourceSummary.total.size, + requestCount: summary.total.count, + byteCount: summary.total.size, }), }; } diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 5f0d6efa2865..25dcc12969a6 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -759,46 +759,10 @@ "message": "{requestCount, plural, =1 {1 request} other {# requests}} • { byteCount, number, bytes } KB", "description": "[ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page." }, - "lighthouse-core/audits/resource-summary.js | documentResourceType": { - "message": "Document", - "description": "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." - }, - "lighthouse-core/audits/resource-summary.js | fontResourceType": { - "message": "Font", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page" - }, - "lighthouse-core/audits/resource-summary.js | imageResourceType": { - "message": "Image", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page" - }, - "lighthouse-core/audits/resource-summary.js | mediaResourceType": { - "message": "Media", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page" - }, - "lighthouse-core/audits/resource-summary.js | otherResourceType": { - "message": "Other", - "description": "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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font." - }, - "lighthouse-core/audits/resource-summary.js | scriptResourceType": { - "message": "Script", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page." - }, - "lighthouse-core/audits/resource-summary.js | stylesheetResourceType": { - "message": "Stylesheet", - "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page." - }, - "lighthouse-core/audits/resource-summary.js | thirdPartyResourceType": { - "message": "Third-party", - "description": "Label for a row in a data table; entries will be the total number and byte size of all third-part resources loaded by a web page" - }, "lighthouse-core/audits/resource-summary.js | title": { "message": "Keep request counts and transfer sizes small", "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." }, - "lighthouse-core/audits/resource-summary.js | totalResourceType": { - "message": "Total", - "description": "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." - }, "lighthouse-core/audits/seo/canonical.js | description": { "message": "Canonical links suggest which URL to show in search results. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/canonical).", "description": "Description of a Lighthouse audit that tells the user *why* they need to have a valid rel=canonical link. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation." @@ -1271,14 +1235,54 @@ "message": "Potential savings of {wastedMs, number, milliseconds} ms", "description": "Label shown per-audit to show how many milliseconds faster the page load could be if the user implemented the suggestions. The `{wastedMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 140 ms)" }, + "lighthouse-core/lib/i18n/i18n.js | documentResourceType": { + "message": "Document", + "description": "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." + }, + "lighthouse-core/lib/i18n/i18n.js | fontResourceType": { + "message": "Font", + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page." + }, + "lighthouse-core/lib/i18n/i18n.js | imageResourceType": { + "message": "Image", + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page." + }, + "lighthouse-core/lib/i18n/i18n.js | mediaResourceType": { + "message": "Media", + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page. 'Media' refers to audio and video files." + }, "lighthouse-core/lib/i18n/i18n.js | ms": { "message": "{timeInMs, number, milliseconds} ms", "description": "Used to show the duration in milliseconds that something lasted. The `{timeInMs}` placeholder will be replaced with the time duration, shown in milliseconds (e.g. 63 ms)" }, + "lighthouse-core/lib/i18n/i18n.js | otherResourceType": { + "message": "Other", + "description": "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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font." + }, + "lighthouse-core/lib/i18n/i18n.js | scriptResourceType": { + "message": "Script", + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. 'Script' refers to JavaScript or other files that are executable by a browser." + }, "lighthouse-core/lib/i18n/i18n.js | seconds": { "message": "{timeInMs, number, seconds} s", "description": "Used to show the duration in seconds that something lasted. The {timeInMs} placeholder will be replaced with the time duration, shown in seconds (e.g. 5.2 s)" }, + "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": { + "message": "Stylesheet", + "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. 'Stylesheet' refers to CSS stylesheets." + }, + "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourcesLabel": { + "message": "Show 3rd-party resources", + "description": "This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or \"3rd-party\") resources in the table, where \"third-party resources\" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page." + }, + "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": { + "message": "Third-party", + "description": "Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page." + }, + "lighthouse-core/lib/i18n/i18n.js | totalResourceType": { + "message": "Total", + "description": "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." + }, "lighthouse-core/lib/lh-error.js | badTraceRecording": { "message": "Something went wrong with recording the trace over your page load. Please run Lighthouse again. ({errorCode})", "description": "Error message explaining that the network trace was not able to be recorded for the Lighthouse run." @@ -1391,10 +1395,6 @@ "message": "Expand snippet", "description": "Label for button that shows all lines of the snippet when clicked" }, - "lighthouse-core/report/html/renderer/util.js | thirdPartyResourcesLabel": { - "message": "Show 3rd-party resources", - "description": "This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or \"3rd-party\") resources in the table, where \"third-party resources\" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page." - }, "lighthouse-core/report/html/renderer/util.js | toplevelWarningsMessage": { "message": "There were issues affecting this run of Lighthouse:", "description": "Label shown preceding any important warnings that may have invalidated the entire report. For example, if the user has Chrome extensions installed, they may add enough performance overhead that Lighthouse's performance metrics are unreliable. If shown, this will be displayed at the top of the report UI." diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 9c4ba39347d5..51a11cbe8a90 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -56,6 +56,26 @@ const UIStrings = { columnWastedMs: 'Potential Savings', /** Label for the time spent column in data tables, entries will be the number of milliseconds spent during a particular activity */ columnTimeSpent: 'Time Spent', + /** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */ + thirdPartyResourcesLabel: 'Show 3rd-party resources', + /** 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. */ + documentResourceType: 'Document', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Script' resources loaded by a web page. 'Script' refers to JavaScript or other files that are executable by a browser. */ + scriptResourceType: 'Script', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. 'Stylesheet' refers to CSS stylesheets. */ + stylesheetResourceType: 'Stylesheet', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Image' resources loaded by a web page. */ + imageResourceType: 'Image', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Media' resources loaded by a web page. 'Media' refers to audio and video files. */ + mediaResourceType: 'Media', + /** Label for a row in a data table; entries will be the total number and byte size of all 'Font' resources loaded by a web page. */ + fontResourceType: 'Font', + /** 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 that don't fit into the categories of Document, Script, Stylesheet, Image, Media, & Font.*/ + otherResourceType: 'Other', + /** Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page. */ + thirdPartyResourceType: 'Third-party', }; const formats = { diff --git a/lighthouse-core/report/html/renderer/util.js b/lighthouse-core/report/html/renderer/util.js index 9b4036e9594a..d2ea58ead6db 100644 --- a/lighthouse-core/report/html/renderer/util.js +++ b/lighthouse-core/report/html/renderer/util.js @@ -577,9 +577,6 @@ Util.UIStrings = { lsPerformanceCategoryDescription: '[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.', /** Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. "Lab" is an abbreviated form of "laboratory", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site. */ labDataTitle: 'Lab Data', - - /** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */ - thirdPartyResourcesLabel: 'Show 3rd-party resources', }; if (typeof module !== 'undefined' && module.exports) { diff --git a/lighthouse-core/test/audits/resource-summary-test.js b/lighthouse-core/test/audits/resource-summary-test.js index 0123fc5a98f2..91005141021e 100644 --- a/lighthouse-core/test/audits/resource-summary-test.js +++ b/lighthouse-core/test/audits/resource-summary-test.js @@ -6,7 +6,6 @@ 'use strict'; const ResourceSummaryAudit = require('../../audits/resource-summary.js'); -const assert = require('assert'); const networkRecordsToDevtoolsLog = require('../network-records-to-devtools-log.js'); /* eslint-env jest */ @@ -29,42 +28,47 @@ describe('Performance: Resource summary audit', () => { }; }); - it('has three table columns', () => { - return ResourceSummaryAudit.audit(artifacts, context).then(result => { - assert.equal(result.details.headings.length, 3); - }); + it('has three table columns', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + expect(result.details.headings.length).toBe(3); }); - it('includes the correct properties for each table item', () => { - return ResourceSummaryAudit.audit(artifacts, context).then(result => { - const item = result.details.items[0]; - assert.equal(item.resourceType, 'total'); - assert.ok(item.label); - assert.equal(item.count, 4); - assert.equal(item.size, 160); - }); + it('has the correct score', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + expect(result.score).toBe(1); }); - it('includes all resource types, regardless of whether page contains them', () => { - return ResourceSummaryAudit.audit(artifacts, context).then(result => { - assert.equal(Object.keys(result.details.items).length, 9); - }); + it('has the correct display value', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + expect(result.displayValue).toBeDisplayString('4 requests • 0 KB'); }); - it('it displays "0" if there are no resources of that type', () => { - return ResourceSummaryAudit.audit(artifacts, context).then(result => { - const fontItem = result.details.items.find(item => item.resourceType === 'font'); - assert.equal(fontItem.count, 0); - assert.equal(fontItem.size, 0); - }); + it('includes the correct properties for each table item', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + const item = result.details.items[0]; + expect(item.resourceType).toEqual('total'); + expect(item.label).toBeDisplayString('Total'); + expect(item.count).toBe(4); + expect(item.size).toBe(160); }); - it('it sorts items by size (descending)', () => { - return ResourceSummaryAudit.audit(artifacts, context).then(result => { - const items = result.details.items; - assert.ok(items[0].size >= items[1].size); - assert.ok(items[1].size >= items[2].size); - assert.ok(items[2].size >= items[3].size); - }); + it('includes all resource types, regardless of whether page contains them', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + expect(Object.keys(result.details.items).length).toBe(9); + }); + + it('it displays "0" if there are no resources of that type', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + const fontItem = result.details.items.find(item => item.resourceType === 'font'); + expect(fontItem.count).toBe(0); + expect(fontItem.size).toBe(0); + }); + + it('it sorts items by size (descending)', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + const items = result.details.items; + expect(items[0].size).toBeGreaterThanOrEqual(items[1].size); + expect(items[1].size).toBeGreaterThanOrEqual(items[2].size); + expect(items[2].size).toBeGreaterThanOrEqual(items[3].size); }); }); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index c2bf6f146fac..6d2ca4aed343 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -1275,7 +1275,7 @@ }, "resource-summary": { "id": "resource-summary", - "title": "Keep request counts and file sizes small", + "title": "Keep request counts and transfer sizes small", "description": "To set budgets for the quantity and size of page resources, add a budget.json file.", "score": null, "scoreDisplayMode": "informative", @@ -1294,9 +1294,9 @@ "text": "Requests" }, { - "key": "size", + "key": "sizpi18e", "itemType": "bytes", - "text": "File Size" + "text": "Transfer Size" } ], "items": [ @@ -4715,19 +4715,28 @@ "auditGroupExpandTooltip": "Show audits", "crcInitialNavigation": "Initial Navigation", "crcLongestDurationLabel": "Maximum critical path latency:", + "documentResourceType": "Document", "errorLabel": "Error!", "errorMissingAuditInfo": "Report error: no audit information", + "fontResourceType": "Font", + "imageResourceType": "Image", "labDataTitle": "Lab Data", "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", "manualAuditsGroupTitle": "Additional items to manually check", + "mediaResourceType": "Media", "notApplicableAuditsGroupTitle": "Not applicable", "opportunityResourceColumnLabel": "Opportunity", "opportunitySavingsColumnLabel": "Estimated Savings", + "otherResourceType": "Other", "passedAuditsGroupTitle": "Passed audits", + "scriptResourceType": "Script", "snippetCollapseButtonLabel": "Collapse snippet", "snippetExpandButtonLabel": "Expand snippet", + "stylesheetResourceType": "Stylesheet", "thirdPartyResourcesLabel": "Show 3rd-party resources", + "thirdPartyResourceType": "Third-party", "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:", + "totalResourceType": "Total", "varianceDisclaimer": "Values are estimated and may vary.", "warningAuditsGroupTitle": "Passed audits but with warnings", "warningHeader": "Warnings: " @@ -4976,33 +4985,6 @@ "path": "audits[resource-summary].displayValue" } ], - "lighthouse-core/audits/resource-summary.js | totalResourceType": [ - "audits[resource-summary].details.items[0].label" - ], - "lighthouse-core/audits/resource-summary.js | scriptResourceType": [ - "audits[resource-summary].details.items[1].label" - ], - "lighthouse-core/audits/resource-summary.js | thirdPartyResourceType": [ - "audits[resource-summary].details.items[2].label" - ], - "lighthouse-core/audits/resource-summary.js | imageResourceType": [ - "audits[resource-summary].details.items[3].label" - ], - "lighthouse-core/audits/resource-summary.js | documentResourceType": [ - "audits[resource-summary].details.items[4].label" - ], - "lighthouse-core/audits/resource-summary.js | otherResourceType": [ - "audits[resource-summary].details.items[5].label" - ], - "lighthouse-core/audits/resource-summary.js | stylesheetResourceType": [ - "audits[resource-summary].details.items[6].label" - ], - "lighthouse-core/audits/resource-summary.js | mediaResourceType": [ - "audits[resource-summary].details.items[7].label" - ], - "lighthouse-core/audits/resource-summary.js | fontResourceType": [ - "audits[resource-summary].details.items[8].label" - ], "lighthouse-core/audits/accessibility/accesskeys.js | title": [ "audits.accesskeys.title" ], diff --git a/proto/sample_v2_round_trip.json b/proto/sample_v2_round_trip.json index 3212277cee01..dfc9ad10d1ce 100644 --- a/proto/sample_v2_round_trip.json +++ b/proto/sample_v2_round_trip.json @@ -2141,7 +2141,91 @@ "score": 0.46, "scoreDisplayMode": "numeric", "title": "Eliminate render-blocking resources" - }, + }, + "resource-summary": { + "description": "To set budgets for the quantity and size of page resources, add a budget.json file.", + "details": { + "type": "table", + "headings": [ + { + "key": "label", + "itemType": "text", + "text": "Resource Type" + }, + { + "key": "count", + "itemType": "numeric", + "text": "Requests" + }, + { + "key": "sizpi18e", + "itemType": "bytes", + "text": "Transfer Size" + } + ], + "items": [ + { + "resourceType": "total", + "label": "Total", + "count": 18, + "size": 160738 + }, + { + "resourceType": "script", + "label": "Script", + "count": 4, + "size": 103675 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "count": 2, + "size": 30174 + }, + { + "resourceType": "image", + "label": "Image", + "count": 2, + "size": 24741 + }, + { + "resourceType": "document", + "label": "Document", + "count": 3, + "size": 14109 + }, + { + "resourceType": "other", + "label": "Other", + "count": 2, + "size": 12861 + }, + { + "resourceType": "stylesheet", + "label": "Stylesheet", + "count": 7, + "size": 5352 + }, + { + "resourceType": "media", + "label": "Media", + "count": 0, + "size": 0 + }, + { + "resourceType": "font", + "label": "Font", + "count": 0, + "size": 0 + } + ] + }, + "displayValue": "18 requests • 157 KB", + "id": "resource-summary", + "score": null, + "scoreDisplayMode": "informative", + "title": "Keep request counts and transfer sizes small" + }, "robots-txt": { "description": "If your robots.txt file is malformed, crawlers may not be able to understand how you want your website to be crawled or indexed.", "id": "robots-txt", @@ -3358,7 +3442,12 @@ "group": "diagnostics", "id": "font-display", "weight": 0.0 - }, + }, + { + "group": "diagnostics", + "id": "resource-summary", + "weight": 0 + }, { "id": "network-requests", "weight": 0.0 @@ -3636,24 +3725,33 @@ "finalUrl": "http://localhost:10200/dobetterweb/dbw_tester.html", "i18n": { "rendererFormattedStrings": { - "auditGroupExpandTooltip": "Show audits", - "crcInitialNavigation": "Initial Navigation", - "crcLongestDurationLabel": "Maximum critical path latency:", - "errorLabel": "Error!", - "errorMissingAuditInfo": "Report error: no audit information", - "labDataTitle": "Lab Data", - "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", - "manualAuditsGroupTitle": "Additional items to manually check", - "notApplicableAuditsGroupTitle": "Not applicable", - "opportunityResourceColumnLabel": "Opportunity", - "opportunitySavingsColumnLabel": "Estimated Savings", - "passedAuditsGroupTitle": "Passed audits", - "snippetCollapseButtonLabel": "Collapse snippet", - "snippetExpandButtonLabel": "Expand snippet", - "thirdPartyResourcesLabel": "Show 3rd-party resources", - "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:", - "varianceDisclaimer": "Values are estimated and may vary.", - "warningAuditsGroupTitle": "Passed audits but with warnings", + "auditGroupExpandTooltip": "Show audits", + "crcInitialNavigation": "Initial Navigation", + "crcLongestDurationLabel": "Maximum critical path latency:", + "documentResourceType": "Document", + "errorLabel": "Error!", + "errorMissingAuditInfo": "Report error: no audit information", + "fontResourceType": "Font", + "imageResourceType": "Image", + "labDataTitle": "Lab Data", + "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", + "manualAuditsGroupTitle": "Additional items to manually check", + "mediaResourceType": "Media", + "notApplicableAuditsGroupTitle": "Not applicable", + "opportunityResourceColumnLabel": "Opportunity", + "opportunitySavingsColumnLabel": "Estimated Savings", + "otherResourceType": "Other", + "passedAuditsGroupTitle": "Passed audits", + "scriptResourceType": "Script", + "snippetCollapseButtonLabel": "Collapse snippet", + "snippetExpandButtonLabel": "Expand snippet", + "stylesheetResourceType": "Stylesheet", + "thirdPartyResourcesLabel": "Show 3rd-party resources", + "thirdPartyResourceType": "Third-party", + "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:", + "totalResourceType": "Total", + "varianceDisclaimer": "Values are estimated and may vary.", + "warningAuditsGroupTitle": "Passed audits but with warnings", "warningHeader": "Warnings: " } }, @@ -4092,7 +4190,13 @@ "entryType": "measure", "name": "lh:audit:offline-start-url", "startTime": 0.0 - }, + }, + { + "duration": 100, + "entryType": "measure", + "name": "lh:audit:resource-summary", + "startTime": 0.0 + }, { "duration": 100.0, "entryType": "measure", diff --git a/types/budget.d.ts b/types/budget.d.ts index 7840164590af..fa8632f1b8d4 100644 --- a/types/budget.d.ts +++ b/types/budget.d.ts @@ -39,7 +39,7 @@ declare global { /** Supported timing metrics. */ export type TimingMetric = 'first-contentful-paint' | 'first-cpu-idle' | 'interactive' | 'first-meaningful-paint' | 'estimated-input-latency'; - /** Supported resource types. */ + /** Supported values for the resourceType property of a ResourceBudget. */ export type ResourceType = 'stylesheet' | 'image' | 'media' | 'font' | 'script' | 'document' | 'other' | 'total' | 'third-party'; } } From fae00516a256bb6ad20f9b6ee0b158b17abcb9cf Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Tue, 30 Apr 2019 18:00:34 -0400 Subject: [PATCH 4/6] lightwallet: Third-party should be last table row --- lighthouse-core/audits/resource-summary.js | 5 ++++ .../test/audits/resource-summary-test.js | 27 ++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js index 665247b0681c..216abce440d8 100644 --- a/lighthouse-core/audits/resource-summary.js +++ b/lighthouse-core/audits/resource-summary.js @@ -81,6 +81,11 @@ class ResourceSummary extends Audit { size: summary[type].size, }; }).sort((a, b) => { + // Sorts table rows to be: + // 1st row: Total + // 2nd to n-1 row: Sorted by descending size + // Last row: Third-party + if (a.resourceType === 'third-party') return 1; return b.size - a.size; }); diff --git a/lighthouse-core/test/audits/resource-summary-test.js b/lighthouse-core/test/audits/resource-summary-test.js index 91005141021e..08be03976ad7 100644 --- a/lighthouse-core/test/audits/resource-summary-test.js +++ b/lighthouse-core/test/audits/resource-summary-test.js @@ -64,11 +64,26 @@ describe('Performance: Resource summary audit', () => { expect(fontItem.size).toBe(0); }); - it('it sorts items by size (descending)', async () => { - const result = await ResourceSummaryAudit.audit(artifacts, context); - const items = result.details.items; - expect(items[0].size).toBeGreaterThanOrEqual(items[1].size); - expect(items[1].size).toBeGreaterThanOrEqual(items[2].size); - expect(items[2].size).toBeGreaterThanOrEqual(items[3].size); + describe('table ordering', () => { + it('except for the last row, it sorts items by size (descending)', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + const items = result.details.items; + items.forEach((item, index) => { + if (index + 2 < items.length) { + expect(item.size).toBeGreaterThanOrEqual(items[index + 1].size); + } + }); + }); + + it('"Total" is the first tow', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + expect(result.details.items[0].resourceType).toBe('total'); + }); + + it('"Third-party" is the last-row', async () => { + const result = await ResourceSummaryAudit.audit(artifacts, context); + const items = result.details.items; + expect(items[items.length - 1].resourceType).toBe('third-party'); + }); }); }); From 838060c82cb55afd3a3832fc367383480f5c41e2 Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Tue, 30 Apr 2019 18:02:43 -0400 Subject: [PATCH 5/6] lightwallet: rm diagnostic styling code --- lighthouse-core/report/html/report-styles.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lighthouse-core/report/html/report-styles.css b/lighthouse-core/report/html/report-styles.css index 0e9fefd49a7d..7421805b3c81 100644 --- a/lighthouse-core/report/html/report-styles.css +++ b/lighthouse-core/report/html/report-styles.css @@ -432,12 +432,6 @@ display: none; } -.lh-audit--informative .lh-audit__score-icon { - border: none; - border-radius: 100%; - background: var(--color-black-400); -} - .lh-audit__description, .lh-audit__stackpack { color: var(--secondary-text-color); From 2ee8053565732b724096fce007673d568df35e08 Mon Sep 17 00:00:00 2001 From: Katie Hempenius Date: Wed, 1 May 2019 00:14:30 -0400 Subject: [PATCH 6/6] LightWallet: more changes to resource-summary audit --- lighthouse-core/audits/resource-summary.js | 35 ++++----- lighthouse-core/lib/i18n/en-US.json | 10 +-- lighthouse-core/lib/i18n/i18n.js | 2 - lighthouse-core/report/html/renderer/util.js | 3 + .../test/audits/resource-summary-test.js | 16 ++-- lighthouse-core/test/results/sample_v2.json | 76 ++++++++++++------- proto/sample_v2_round_trip.json | 49 ++++++------ 7 files changed, 104 insertions(+), 87 deletions(-) diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js index 216abce440d8..b39add3ae424 100644 --- a/lighthouse-core/audits/resource-summary.js +++ b/lighthouse-core/audits/resource-summary.js @@ -6,14 +6,12 @@ 'use strict'; const Audit = require('./audit.js'); -const NetworkRecords = require('../computed/network-records.js'); const ComputedResourceSummary = require('../computed/resource-summary.js'); const i18n = require('../lib/i18n/i18n.js'); -const MainResource = require('../computed/main-resource.js'); const UIStrings = { /** Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page. */ - title: 'Keep request counts and transfer sizes small', + title: 'Keep request counts low and transfer sizes small', /** Description of a Lighthouse audit that tells the user that they can setup a budgets for the quantity and size of page resources. No character length limits. */ description: 'To set budgets for the quantity and size of page resources,' + ' add a budget.json file.', @@ -34,7 +32,7 @@ class ResourceSummary extends Audit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, - requiredArtifacts: ['devtoolsLogs'], + requiredArtifacts: ['devtoolsLogs', 'URL'], }; } @@ -45,15 +43,14 @@ class ResourceSummary extends Audit { */ static async audit(artifacts, context) { const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS]; - const networkRecords = await NetworkRecords.request(devtoolsLog, context); - const mainResource = await MainResource.request({devtoolsLog, URL: artifacts.URL}, context); - const summary = ComputedResourceSummary.summarize(networkRecords, mainResource.url); + const summary = await ComputedResourceSummary + .request({devtoolsLog, URL: artifacts.URL}, context); /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'label', itemType: 'text', text: 'Resource Type'}, - {key: 'count', itemType: 'numeric', text: 'Requests'}, - {key: 'sizpi18e', itemType: 'bytes', text: 'Transfer Size'}, + {key: 'requestCount', itemType: 'numeric', text: 'Requests'}, + {key: 'size', itemType: 'bytes', text: 'Transfer Size'}, ]; @@ -71,25 +68,25 @@ class ResourceSummary extends Audit { }; const types = /** @type {Array} */ (Object.keys(summary)); - const tableContents = types.map(type => { + const rows = types.map(type => { return { // ResourceType is included as an "id" for ease of use. // It does not appear directly in the table. resourceType: type, label: strMappings[type], - count: summary[type].count, + requestCount: summary[type].count, size: summary[type].size, }; - }).sort((a, b) => { - // Sorts table rows to be: - // 1st row: Total - // 2nd to n-1 row: Sorted by descending size - // Last row: Third-party - if (a.resourceType === 'third-party') return 1; - return b.size - a.size; }); + // Force third-party to be last, descending by size otherwise + const thirdPartyRow = rows.find(r => r.resourceType === 'third-party') || []; + const otherRows = rows.filter(r => r.resourceType !== 'third-party') + .sort((a, b) => { + return b.size - a.size; + }); + const tableItems = otherRows.concat(thirdPartyRow); - const tableDetails = Audit.makeTableDetails(headings, tableContents); + const tableDetails = Audit.makeTableDetails(headings, tableItems); return { details: tableDetails, diff --git a/lighthouse-core/lib/i18n/en-US.json b/lighthouse-core/lib/i18n/en-US.json index 25dcc12969a6..02716a56e9d6 100644 --- a/lighthouse-core/lib/i18n/en-US.json +++ b/lighthouse-core/lib/i18n/en-US.json @@ -760,7 +760,7 @@ "description": "[ICU Syntax] Label for an audit identifying the number of requests and kilobytes used to load the page." }, "lighthouse-core/audits/resource-summary.js | title": { - "message": "Keep request counts and transfer sizes small", + "message": "Keep request counts low and transfer sizes small", "description": "Imperative title of a Lighthouse audit that tells the user to minimize the size and quantity of resources used to load the page." }, "lighthouse-core/audits/seo/canonical.js | description": { @@ -1271,10 +1271,6 @@ "message": "Stylesheet", "description": "Label for a row in a data table; entries will be the total number and byte size of all 'Stylesheet' resources loaded by a web page. 'Stylesheet' refers to CSS stylesheets." }, - "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourcesLabel": { - "message": "Show 3rd-party resources", - "description": "This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or \"3rd-party\") resources in the table, where \"third-party resources\" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page." - }, "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": { "message": "Third-party", "description": "Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page." @@ -1395,6 +1391,10 @@ "message": "Expand snippet", "description": "Label for button that shows all lines of the snippet when clicked" }, + "lighthouse-core/report/html/renderer/util.js | thirdPartyResourcesLabel": { + "message": "Show 3rd-party resources", + "description": "This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or \"3rd-party\") resources in the table, where \"third-party resources\" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page." + }, "lighthouse-core/report/html/renderer/util.js | toplevelWarningsMessage": { "message": "There were issues affecting this run of Lighthouse:", "description": "Label shown preceding any important warnings that may have invalidated the entire report. For example, if the user has Chrome extensions installed, they may add enough performance overhead that Lighthouse's performance metrics are unreliable. If shown, this will be displayed at the top of the report UI." diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 51a11cbe8a90..b93423b4a83f 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -56,8 +56,6 @@ const UIStrings = { columnWastedMs: 'Potential Savings', /** Label for the time spent column in data tables, entries will be the number of milliseconds spent during a particular activity */ columnTimeSpent: 'Time Spent', - /** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */ - thirdPartyResourcesLabel: 'Show 3rd-party resources', /** 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. */ diff --git a/lighthouse-core/report/html/renderer/util.js b/lighthouse-core/report/html/renderer/util.js index d2ea58ead6db..9b4036e9594a 100644 --- a/lighthouse-core/report/html/renderer/util.js +++ b/lighthouse-core/report/html/renderer/util.js @@ -577,6 +577,9 @@ Util.UIStrings = { lsPerformanceCategoryDescription: '[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.', /** Title of the lab data section of the Performance category. Within this section are various speed metrics which quantify the pageload performance into values presented in seconds and milliseconds. "Lab" is an abbreviated form of "laboratory", and refers to the fact that the data is from a controlled test of a website, not measurements from real users visiting that site. */ labDataTitle: 'Lab Data', + + /** This label is for a checkbox above a table of items loaded by a web page. The checkbox is used to show or hide third-party (or "3rd-party") resources in the table, where "third-party resources" refers to items loaded by a web page from URLs that aren't controlled by the owner of the web page. */ + thirdPartyResourcesLabel: 'Show 3rd-party resources', }; if (typeof module !== 'undefined' && module.exports) { diff --git a/lighthouse-core/test/audits/resource-summary-test.js b/lighthouse-core/test/audits/resource-summary-test.js index 08be03976ad7..0b745ff38232 100644 --- a/lighthouse-core/test/audits/resource-summary-test.js +++ b/lighthouse-core/test/audits/resource-summary-test.js @@ -30,7 +30,7 @@ describe('Performance: Resource summary audit', () => { it('has three table columns', async () => { const result = await ResourceSummaryAudit.audit(artifacts, context); - expect(result.details.headings.length).toBe(3); + expect(result.details.headings).toHaveLength(3); }); it('has the correct score', async () => { @@ -48,19 +48,19 @@ describe('Performance: Resource summary audit', () => { const item = result.details.items[0]; expect(item.resourceType).toEqual('total'); expect(item.label).toBeDisplayString('Total'); - expect(item.count).toBe(4); + expect(item.requestCount).toBe(4); expect(item.size).toBe(160); }); it('includes all resource types, regardless of whether page contains them', async () => { const result = await ResourceSummaryAudit.audit(artifacts, context); - expect(Object.keys(result.details.items).length).toBe(9); + expect(Object.keys(result.details.items)).toHaveLength(9); }); it('it displays "0" if there are no resources of that type', async () => { const result = await ResourceSummaryAudit.audit(artifacts, context); const fontItem = result.details.items.find(item => item.resourceType === 'font'); - expect(fontItem.count).toBe(0); + expect(fontItem.requestCount).toBe(0); expect(fontItem.size).toBe(0); }); @@ -68,14 +68,12 @@ describe('Performance: Resource summary audit', () => { it('except for the last row, it sorts items by size (descending)', async () => { const result = await ResourceSummaryAudit.audit(artifacts, context); const items = result.details.items; - items.forEach((item, index) => { - if (index + 2 < items.length) { - expect(item.size).toBeGreaterThanOrEqual(items[index + 1].size); - } + items.slice(0, -2).forEach((item, index) => { + expect(item.size).toBeGreaterThanOrEqual(items[index + 1].size); }); }); - it('"Total" is the first tow', async () => { + it('"Total" is the first row', async () => { const result = await ResourceSummaryAudit.audit(artifacts, context); expect(result.details.items[0].resourceType).toBe('total'); }); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index 6d2ca4aed343..ece7e5480c24 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -1275,7 +1275,7 @@ }, "resource-summary": { "id": "resource-summary", - "title": "Keep request counts and transfer sizes small", + "title": "Keep request counts low and transfer sizes small", "description": "To set budgets for the quantity and size of page resources, add a budget.json file.", "score": null, "scoreDisplayMode": "informative", @@ -1289,12 +1289,12 @@ "text": "Resource Type" }, { - "key": "count", + "key": "requestCount", "itemType": "numeric", "text": "Requests" }, { - "key": "sizpi18e", + "key": "size", "itemType": "bytes", "text": "Transfer Size" } @@ -1303,56 +1303,56 @@ { "resourceType": "total", "label": "Total", - "count": 18, + "requestCount": 18, "size": 160738 }, { "resourceType": "script", "label": "Script", - "count": 4, + "requestCount": 4, "size": 103675 }, - { - "resourceType": "third-party", - "label": "Third-party", - "count": 2, - "size": 30174 - }, { "resourceType": "image", "label": "Image", - "count": 2, + "requestCount": 2, "size": 24741 }, { "resourceType": "document", "label": "Document", - "count": 3, + "requestCount": 3, "size": 14109 }, { "resourceType": "other", "label": "Other", - "count": 2, + "requestCount": 2, "size": 12861 }, { "resourceType": "stylesheet", "label": "Stylesheet", - "count": 7, + "requestCount": 7, "size": 5352 }, { "resourceType": "media", "label": "Media", - "count": 0, + "requestCount": 0, "size": 0 }, { "resourceType": "font", "label": "Font", - "count": 0, + "requestCount": 0, "size": 0 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "requestCount": 2, + "size": 30174 } ] } @@ -4185,6 +4185,12 @@ "duration": 100, "entryType": "measure" }, + { + "startTime": 0, + "name": "lh:computed:ResourceSummary", + "duration": 100, + "entryType": "measure" + }, { "startTime": 0, "name": "lh:audit:pwa-cross-browser", @@ -4715,28 +4721,19 @@ "auditGroupExpandTooltip": "Show audits", "crcInitialNavigation": "Initial Navigation", "crcLongestDurationLabel": "Maximum critical path latency:", - "documentResourceType": "Document", "errorLabel": "Error!", "errorMissingAuditInfo": "Report error: no audit information", - "fontResourceType": "Font", - "imageResourceType": "Image", "labDataTitle": "Lab Data", "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", "manualAuditsGroupTitle": "Additional items to manually check", - "mediaResourceType": "Media", "notApplicableAuditsGroupTitle": "Not applicable", "opportunityResourceColumnLabel": "Opportunity", "opportunitySavingsColumnLabel": "Estimated Savings", - "otherResourceType": "Other", "passedAuditsGroupTitle": "Passed audits", - "scriptResourceType": "Script", "snippetCollapseButtonLabel": "Collapse snippet", "snippetExpandButtonLabel": "Expand snippet", - "stylesheetResourceType": "Stylesheet", "thirdPartyResourcesLabel": "Show 3rd-party resources", - "thirdPartyResourceType": "Third-party", "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:", - "totalResourceType": "Total", "varianceDisclaimer": "Values are estimated and may vary.", "warningAuditsGroupTitle": "Passed audits but with warnings", "warningHeader": "Warnings: " @@ -4985,6 +4982,33 @@ "path": "audits[resource-summary].displayValue" } ], + "lighthouse-core/lib/i18n/i18n.js | totalResourceType": [ + "audits[resource-summary].details.items[0].label" + ], + "lighthouse-core/lib/i18n/i18n.js | scriptResourceType": [ + "audits[resource-summary].details.items[1].label" + ], + "lighthouse-core/lib/i18n/i18n.js | imageResourceType": [ + "audits[resource-summary].details.items[2].label" + ], + "lighthouse-core/lib/i18n/i18n.js | documentResourceType": [ + "audits[resource-summary].details.items[3].label" + ], + "lighthouse-core/lib/i18n/i18n.js | otherResourceType": [ + "audits[resource-summary].details.items[4].label" + ], + "lighthouse-core/lib/i18n/i18n.js | stylesheetResourceType": [ + "audits[resource-summary].details.items[5].label" + ], + "lighthouse-core/lib/i18n/i18n.js | mediaResourceType": [ + "audits[resource-summary].details.items[6].label" + ], + "lighthouse-core/lib/i18n/i18n.js | fontResourceType": [ + "audits[resource-summary].details.items[7].label" + ], + "lighthouse-core/lib/i18n/i18n.js | thirdPartyResourceType": [ + "audits[resource-summary].details.items[8].label" + ], "lighthouse-core/audits/accessibility/accesskeys.js | title": [ "audits.accesskeys.title" ], diff --git a/proto/sample_v2_round_trip.json b/proto/sample_v2_round_trip.json index dfc9ad10d1ce..5f1ec1314c4b 100644 --- a/proto/sample_v2_round_trip.json +++ b/proto/sample_v2_round_trip.json @@ -2153,12 +2153,12 @@ "text": "Resource Type" }, { - "key": "count", + "key": "requestCount", "itemType": "numeric", "text": "Requests" }, { - "key": "sizpi18e", + "key": "size", "itemType": "bytes", "text": "Transfer Size" } @@ -2167,56 +2167,56 @@ { "resourceType": "total", "label": "Total", - "count": 18, + "requestCount": 18, "size": 160738 }, { "resourceType": "script", "label": "Script", - "count": 4, + "requestCount": 4, "size": 103675 }, - { - "resourceType": "third-party", - "label": "Third-party", - "count": 2, - "size": 30174 - }, { "resourceType": "image", "label": "Image", - "count": 2, + "requestCount": 2, "size": 24741 }, { "resourceType": "document", "label": "Document", - "count": 3, + "requestCount": 3, "size": 14109 }, { "resourceType": "other", "label": "Other", - "count": 2, + "requestCount": 2, "size": 12861 }, { "resourceType": "stylesheet", "label": "Stylesheet", - "count": 7, + "requestCount": 7, "size": 5352 }, { "resourceType": "media", "label": "Media", - "count": 0, + "requestCount": 0, "size": 0 }, { "resourceType": "font", "label": "Font", - "count": 0, + "requestCount": 0, "size": 0 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "requestCount": 2, + "size": 30174 } ] }, @@ -2224,7 +2224,7 @@ "id": "resource-summary", "score": null, "scoreDisplayMode": "informative", - "title": "Keep request counts and transfer sizes small" + "title": "Keep request counts low and transfer sizes small" }, "robots-txt": { "description": "If your robots.txt file is malformed, crawlers may not be able to understand how you want your website to be crawled or indexed.", @@ -3728,28 +3728,19 @@ "auditGroupExpandTooltip": "Show audits", "crcInitialNavigation": "Initial Navigation", "crcLongestDurationLabel": "Maximum critical path latency:", - "documentResourceType": "Document", "errorLabel": "Error!", "errorMissingAuditInfo": "Report error: no audit information", - "fontResourceType": "Font", - "imageResourceType": "Image", "labDataTitle": "Lab Data", "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.", "manualAuditsGroupTitle": "Additional items to manually check", - "mediaResourceType": "Media", "notApplicableAuditsGroupTitle": "Not applicable", "opportunityResourceColumnLabel": "Opportunity", "opportunitySavingsColumnLabel": "Estimated Savings", - "otherResourceType": "Other", "passedAuditsGroupTitle": "Passed audits", - "scriptResourceType": "Script", "snippetCollapseButtonLabel": "Collapse snippet", "snippetExpandButtonLabel": "Expand snippet", - "stylesheetResourceType": "Stylesheet", "thirdPartyResourcesLabel": "Show 3rd-party resources", - "thirdPartyResourceType": "Third-party", "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:", - "totalResourceType": "Total", "varianceDisclaimer": "Values are estimated and may vary.", "warningAuditsGroupTitle": "Passed audits but with warnings", "warningHeader": "Warnings: " @@ -4197,6 +4188,12 @@ "name": "lh:audit:resource-summary", "startTime": 0.0 }, + { + "duration": 100, + "entryType": "measure", + "name": "lh:computed:ResourceSummary", + "startTime": 0.0 + }, { "duration": 100.0, "entryType": "measure",