From 38e8cd3de8d226f9e809bf0955b99ac57de9daba Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Fri, 24 Jul 2020 18:22:32 -0700 Subject: [PATCH 01/23] Work in progress audit for issues catch-all --- .../dobetterweb/has-inspector-issues.js | 69 +++++++++++++++++++ lighthouse-core/audits/errors-in-console.js | 4 +- lighthouse-core/config/default-config.js | 2 + .../gather/gatherers/inspector-issues.js | 39 ++++++++--- lighthouse-core/lib/i18n/i18n.js | 2 + package.json | 2 +- types/artifacts.d.ts | 4 ++ yarn.lock | 8 +-- 8 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 lighthouse-core/audits/dobetterweb/has-inspector-issues.js diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js new file mode 100644 index 000000000000..4046456c260a --- /dev/null +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -0,0 +1,69 @@ +/** + * @license Copyright 2020 The Lighthouse Authors. 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 i18n = require('../../lib/i18n/i18n.js'); + +const UIStrings = { + /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when no issues were logged into the devtools Issues panel. */ + title: 'No issues in the Issues panel', + /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when issues are detected and logged into the devtools Issues panel. */ + failureTitle: 'Browser errors were logged to the console', + /** Description of a Lighthouse audit that tells the user why issues being logged to the devtools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ + description: 'Description TBD', + /** Table column header for the type of issue. */ + columnIssueType: 'Issue Type', +}; + +const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + +class IssuesPanelEntries extends Audit { + /** + * @return {LH.Audit.Meta} + */ + static get meta() { + return { + id: 'has-inspector-issues', + title: str_(UIStrings.title), + failureTitle: str_(UIStrings.failureTitle), + description: str_(UIStrings.description), + requiredArtifacts: ['InspectorIssues'], + }; + } + + /** + * @param {LH.Artifacts} artifacts + * @return {LH.Audit.Product} + */ + static audit(artifacts) { + + const headings = [ + {key: 'issueType', itemType: 'text', text: str_(UIStrings.columnIssueType)}, + {key: 'reason', itemType: 'text', text: 'Reason'}, + ]; + + const issues = artifacts.InspectorIssues; + const items = []; + + for (const [issueType, issuesOfType] of Object.entries(issues)) { + for (const issue of issuesOfType) { + items.push({ + issueType, + reason: issue.reason || issue.violatedDirective || issue.insecureURL, + }); + } + } + + return { + score: 1, + details: Audit.makeTableDetails(headings, items), + }; + } +} + +module.exports = IssuesPanelEntries; +module.exports.UIStrings = UIStrings; diff --git a/lighthouse-core/audits/errors-in-console.js b/lighthouse-core/audits/errors-in-console.js index 5e574e63ed39..5fe95b89c9c8 100644 --- a/lighthouse-core/audits/errors-in-console.js +++ b/lighthouse-core/audits/errors-in-console.js @@ -23,8 +23,6 @@ const UIStrings = { description: 'Errors logged to the console indicate unresolved problems. ' + 'They can come from network request failures and other browser concerns. ' + '[Learn more](https://web.dev/errors-in-console/)', - /** Label for a column in a data table; entries in the column will be the descriptions of logged browser errors. */ - columnDesc: 'Description', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -116,7 +114,7 @@ class ErrorLogs extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'url', itemType: 'url', text: str_(i18n.UIStrings.columnURL)}, - {key: 'description', itemType: 'code', text: str_(UIStrings.columnDesc)}, + {key: 'description', itemType: 'code', text: str_(i18n.UIStrings.columnDescription)}, ]; const details = Audit.makeTableDetails(headings, tableRows); diff --git a/lighthouse-core/config/default-config.js b/lighthouse-core/config/default-config.js index 19a06ce9ca0c..1152d4a15e36 100644 --- a/lighthouse-core/config/default-config.js +++ b/lighthouse-core/config/default-config.js @@ -313,6 +313,7 @@ const defaultConfig = { 'dobetterweb/dom-size', 'dobetterweb/external-anchors-use-rel-noopener', 'dobetterweb/geolocation-on-start', + 'dobetterweb/has-inspector-issues', 'dobetterweb/no-document-write', 'dobetterweb/no-vulnerable-libraries', 'dobetterweb/js-libraries', @@ -563,6 +564,7 @@ const defaultConfig = { {id: 'js-libraries', weight: 0, group: 'best-practices-general'}, {id: 'deprecations', weight: 1, group: 'best-practices-general'}, {id: 'errors-in-console', weight: 1, group: 'best-practices-general'}, + {id: 'has-inspector-issues', weight: 1, group: 'best-practices-general'}, ], }, 'seo': { diff --git a/lighthouse-core/gather/gatherers/inspector-issues.js b/lighthouse-core/gather/gatherers/inspector-issues.js index 29a54cf5cecf..b28a9203bf57 100644 --- a/lighthouse-core/gather/gatherers/inspector-issues.js +++ b/lighthouse-core/gather/gatherers/inspector-issues.js @@ -38,28 +38,47 @@ class InspectorIssues extends Gatherer { /** * @param {LH.Gatherer.PassContext} passContext - * @param {LH.Gatherer.LoadData} loadData * @return {Promise} */ - async afterPass(passContext, loadData) { + async afterPass(passContext) { const driver = passContext.driver; - const networkRecords = loadData.networkRecords; driver.off('Audits.issueAdded', this._onIssueAdded); await driver.sendCommand('Audits.disable'); const artifact = { /** @type {Array} */ mixedContent: [], + /** @type {Array} */ + sameSiteCookies: [], + /** @type {Array} */ + blockedByResponse: [], + /** @type {Array} */ + heavyAds: [], + /** @type {Array} */ + contentSecurityPolicy: [], }; for (const issue of this._issues) { - if (issue.details.mixedContentIssueDetails) { - const issueDetails = issue.details.mixedContentIssueDetails; - const issueReqId = issueDetails.request && issueDetails.request.requestId; - if (issueReqId && - networkRecords.find(req => req.requestId === issueReqId)) { - artifact.mixedContent.push(issue.details.mixedContentIssueDetails); - } + switch (issue.code) { + case 'MixedContentIssue': + issue.details.mixedContentIssueDetails && + artifact.mixedContent.push(issue.details.mixedContentIssueDetails); + break; + case 'SameSiteCookieIssue': + issue.details.sameSiteCookieIssueDetails && + artifact.sameSiteCookies.push(issue.details.sameSiteCookieIssueDetails); + break; + case 'BlockedByResponseIssue': + issue.details.blockedByResponseIssueDetails && + artifact.blockedByResponse.push(issue.details.blockedByResponseIssueDetails); + break; + case 'HeavyAdIssue': + issue.details.heavyAdIssueDetails && + artifact.heavyAds.push(issue.details.heavyAdIssueDetails); + break; + case 'ContentSecurityPolicyIssue': + issue.details.contentSecurityPolicyIssueDetails && + artifact.contentSecurityPolicy.push(issue.details.contentSecurityPolicyIssueDetails); } } diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index eec8d71a3a01..99084c44ae05 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -88,6 +88,8 @@ const UIStrings = { columnStartTime: 'Start Time', /** Label for a column in a data table; entries will be the total number of milliseconds from the start time until the end time. */ columnDuration: 'Duration', + /** Label for a column in a data table; entries will be a description of the table item. */ + columnDescription: '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. */ 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/package.json b/package.json index 334f0f5e26bc..485a39f497a8 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "cross-env": "^7.0.2", "csv-validator": "^0.0.3", "cz-customizable": "^5.2.0", - "devtools-protocol": "0.0.770484", + "devtools-protocol": "0.0.790520", "eslint": "^4.19.1", "eslint-config-google": "^0.9.1", "eslint-plugin-local-rules": "0.1.0", diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index 6cf7c9cbc763..ac3b2d342356 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -511,6 +511,10 @@ declare global { export interface InspectorIssues { mixedContent: Crdp.Audits.MixedContentIssueDetails[]; + sameSiteCookies: Crdp.Audits.SameSiteCookieIssueDetails[]; + blockedByResponse: Crdp.Audits.BlockedByResponseIssueDetails[]; + heavyAds: Crdp.Audits.HeavyAdIssueDetails[]; + contentSecurityPolicy: Crdp.Audits.ContentSecurityPolicyIssueDetails[]; } // Computed artifact types below. diff --git a/yarn.lock b/yarn.lock index 2103ee0a5866..7387c6262c09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,10 +2725,10 @@ detective@^5.0.2: defined "^1.0.0" minimist "^1.1.1" -devtools-protocol@0.0.770484: - version "0.0.770484" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.770484.tgz#e7e779431903c7295fd6c5cb118193f74502b9da" - integrity sha512-R99WYb9iVcUAjWBK+1DNpqKDsK/LKfBr+u6AJjTHrydqi2TRywZQs90R2tnI1nCzd7HlLrAnM9Yw4mjIAaokLQ== +devtools-protocol@0.0.790520: + version "0.0.790520" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.790520.tgz#c7b72d42345c53c506c2a886c9631fcd3a276810" + integrity sha512-H8pG4/xFedZNntd8klkpLyLBB6zxDzPHDNXxALATtNF6sLaR8zo1A/Lym1/7OC23BflKWsbOoPS3cyFCBTMV2w== diff-sequences@^24.9.0: version "24.9.0" From 6aa9591399b3f317fb24566b4b483f41e69b6ab6 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Tue, 28 Jul 2020 14:29:21 -0700 Subject: [PATCH 02/23] Add stub strings --- .../dobetterweb/has-inspector-issues.js | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 4046456c260a..01754182c789 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -12,14 +12,32 @@ const UIStrings = { /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when no issues were logged into the devtools Issues panel. */ title: 'No issues in the Issues panel', /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when issues are detected and logged into the devtools Issues panel. */ - failureTitle: 'Browser errors were logged to the console', + failureTitle: 'Isssues were logged in the Issues panel', /** Description of a Lighthouse audit that tells the user why issues being logged to the devtools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ description: 'Description TBD', /** Table column header for the type of issue. */ columnIssueType: 'Issue Type', + /** Message shown in a data table when the item is a SameSiteCookie issue. */ + sameSiteMsg: 'This is a SameSite Cookies issue', + /** Message shown in a data table when the item is a MixedContent issue. */ + mixedContentMsg: 'This is a Mixed Content issue', + /** Message shown in a data table when the item is a BlockedByResponse issue. */ + blockedByResponseMsg: 'This is a Blocked By Response issue', + /** Message shown in a data table when the item is a HeavyAds issue. */ + heavyAdsMsg: 'This is a Heavy Ads issue', + /** Message shown in a data table when the item is a ContentSecurityPolicy issue. */ + contentSecurityPolicyMsg: 'This is a Content Security Policy issue', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); +/** @type {Object} */ +const issueMap = { + 'sameSiteCookies': str_(UIStrings.sameSiteMsg), + 'mixedContent': str_(UIStrings.mixedContentMsg), + 'blockedByResponse': str_(UIStrings.blockedByResponseMsg), + 'heavyAds': str_(UIStrings.heavyAdsMsg), + 'contentSecurityPolicy': str_(UIStrings.contentSecurityPolicyMsg), +}; class IssuesPanelEntries extends Audit { /** @@ -40,7 +58,7 @@ class IssuesPanelEntries extends Audit { * @return {LH.Audit.Product} */ static audit(artifacts) { - + /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'issueType', itemType: 'text', text: str_(UIStrings.columnIssueType)}, {key: 'reason', itemType: 'text', text: 'Reason'}, @@ -50,16 +68,16 @@ class IssuesPanelEntries extends Audit { const items = []; for (const [issueType, issuesOfType] of Object.entries(issues)) { - for (const issue of issuesOfType) { + for (const _ of issuesOfType) { items.push({ issueType, - reason: issue.reason || issue.violatedDirective || issue.insecureURL, + reason: issueMap[issueType], }); } } return { - score: 1, + score: items.length > 0 ? 0 : 1, details: Audit.makeTableDetails(headings, items), }; } From dfba51c05fa29042af7e474e0633b939851fe44e Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 6 Aug 2020 05:16:02 -0700 Subject: [PATCH 03/23] WIP --- .../dobetterweb/has-inspector-issues.js | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 01754182c789..418d110adf40 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -53,6 +53,77 @@ class IssuesPanelEntries extends Audit { }; } + /** + * @param {Array} mixedContentIssues + * @return {Array} + */ + static getMixedContentItems(mixedContentIssues) { + if (!mixedContentIssues) { + return []; + } + + return mixedContentIssues.map(issue => { + + }); + } + + /** + * @param {Array} sameSiteCookieIssues + * @return {Array} + */ + static getSameSiteCookieItems(sameSiteCookieIssues) { + if (!sameSiteCookieIssues) { + return []; + } + + return sameSiteCookieIssues.map(issue => { + + }); + } + + /** + * @param {Array} blockedByResponseIssues + * @return {Array} + */ + static getBlockedByResponseItems(blockedByResponseIssues) { + if (!blockedByResponseIssues) { + return []; + } + + return blockedByResponseIssues.map(issue => { + const blockedReason = issue.reason; + + }); + } + + /** + * @param {Array} heavyAdsIssues + * @return {Array} + */ + static getHeavyAdsItems(heavyAdsIssues) { + if (!heavyAdsIssues) { + return []; + } + + return heavyAdsIssues.map(issue => { + + }); + } + + /** + * @param {Array} cspIssues + * @return {Array} + */ + static getContentSecurityPolicyItems(cspIssues) { + if (!cspIssues) { + return []; + } + + return cspIssues.map(issue => { + + }); + } + /** * @param {LH.Artifacts} artifacts * @return {LH.Audit.Product} From 1b89955e43655168e9a286f2e9bdfb04c607a8cf Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 10 Sep 2020 11:58:24 -0700 Subject: [PATCH 04/23] Update structure --- .../dobetterweb/has-inspector-issues.js | 38 +++++++++++++++---- package.json | 2 +- yarn.lock | 8 ++-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 418d110adf40..284b24037e57 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -39,6 +39,8 @@ const issueMap = { 'contentSecurityPolicy': str_(UIStrings.contentSecurityPolicyMsg), }; +/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ + class IssuesPanelEntries extends Audit { /** * @return {LH.Audit.Meta} @@ -77,7 +79,12 @@ class IssuesPanelEntries extends Audit { } return sameSiteCookieIssues.map(issue => { - + const requestUrl = issue.request && issue.request.url; + return { + issueType: 'SameSite Cookie', + description: str_(UIStrings.sameSiteMsg), + requestUrl: requestUrl || issue.cookieUrl, + }; }); } @@ -92,7 +99,9 @@ class IssuesPanelEntries extends Audit { return blockedByResponseIssues.map(issue => { const blockedReason = issue.reason; - + return { + issueType: 'Blocked By Response' + } }); } @@ -132,18 +141,31 @@ class IssuesPanelEntries extends Audit { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ {key: 'issueType', itemType: 'text', text: str_(UIStrings.columnIssueType)}, - {key: 'reason', itemType: 'text', text: 'Reason'}, + {key: 'description', itemType: 'text', text: str_(i18n.UIStrings.columnDescription)}, + {key: 'requestUrl', itemType: 'url', text: 'Request URL'}, ]; const issues = artifacts.InspectorIssues; + /** @type {Array} */ const items = []; for (const [issueType, issuesOfType] of Object.entries(issues)) { - for (const _ of issuesOfType) { - items.push({ - issueType, - reason: issueMap[issueType], - }); + switch(issueType) { + case 'sameSiteCookies': + items.push(...this.getSameSiteCookieItems(issuesOfType)); + break; + case 'mixedContent': + items.push(...this.getMixedContentItems(issuesOfType)); + break; + case 'blockedByResponse': + items.push(...this.getBlockedByResponseItems(issuesOfType)); + break; + case 'heavyAds': + items.push(...this.getHeavyAdsItems(issuesOfType)); + break; + case 'contentSecurityPolicy': + items.push(...this.getContentSecurityPolicyItems(issuesOfType)); + break; } } diff --git a/package.json b/package.json index c6dce2dfb152..7bae0ea1e815 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "cross-env": "^7.0.2", "csv-validator": "^0.0.3", "cz-customizable": "^5.2.0", - "devtools-protocol": "0.0.801017", + "devtools-protocol": "0.0.805376", "eslint": "^4.19.1", "eslint-config-google": "^0.9.1", "eslint-plugin-local-rules": "0.1.0", diff --git a/yarn.lock b/yarn.lock index 004879746763..40678766b311 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2872,10 +2872,10 @@ detective@^5.0.2: defined "^1.0.0" minimist "^1.1.1" -devtools-protocol@0.0.801017: - version "0.0.801017" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.801017.tgz#340754ebff17b73ddea1b15716ec53887261372c" - integrity sha512-vsOhv/pe1CV3yO3d8ZCRuLlu9FY0Kw4P5TVIC6htjyVfNeklCpFmUrEfvY0ju/y9dyAgwiOhe7pcreRh4/EaZw== +devtools-protocol@0.0.805376: + version "0.0.805376" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.805376.tgz#7ea29e412bfea69e9f2e77bcbafe83c898ad23bd" + integrity sha512-hZBiZTkVOAiWN7eI3oL1ftYtSi/HN8qn7/QYtDUNf9qVCG9/8pt+KyhL3Qoat6nXgiYiyreaz0mr6iB9Edw/sw== diff-sequences@^24.9.0: version "24.9.0" From 20b19739b322cbe71fe2ee1c4c750ac3c5844ba6 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 10 Sep 2020 16:38:47 -0700 Subject: [PATCH 05/23] Updated audit with draft strings --- .../dobetterweb/has-inspector-issues.js | 109 +++++++++++++----- 1 file changed, 83 insertions(+), 26 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 284b24037e57..0da87b400eb3 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -18,28 +18,63 @@ const UIStrings = { /** Table column header for the type of issue. */ columnIssueType: 'Issue Type', /** Message shown in a data table when the item is a SameSiteCookie issue. */ - sameSiteMsg: 'This is a SameSite Cookies issue', - /** Message shown in a data table when the item is a MixedContent issue. */ - mixedContentMsg: 'This is a Mixed Content issue', - /** Message shown in a data table when the item is a BlockedByResponse issue. */ - blockedByResponseMsg: 'This is a Blocked By Response issue', - /** Message shown in a data table when the item is a HeavyAds issue. */ - heavyAdsMsg: 'This is a Heavy Ads issue', - /** Message shown in a data table when the item is a ContentSecurityPolicy issue. */ - contentSecurityPolicyMsg: 'This is a Content Security Policy issue', + sameSiteMessage: 'This is a SameSite Cookies issue', + /** Message shown in a data table when the item is a MixedContent issue. This is when some resources are loaded over an insecure HTTP connection. */ + mixedContentMessage: 'Some resources like images, stylesheets or scripts ' + + 'are being accessed over an insecure HTTP connection', + /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a resource is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ + coepResourceBlockedMessage: 'A resource was blocked due to not being ' + + 'allowed by a Cross-Origin Embedder Policy', + /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a frame is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ + coepFrameBlockedMessage: 'A frame was blocked due to not being ' + + 'allowed by a Cross-Origin Embedder Policy', + /** Message shown in a data table when the item is a BlockedByResponse issue. This is when navigation to a document with a Cross-Origin Opener Policy is blocked. */ + coopIframeBlockedMessage: 'An iframe navigation to a document with ' + + 'a Cross-Origin Opener Policy was blocked', + /** Message shown in a data table when the item is a HeavyAds issue where an ad uses more than 4 megabytes of network bandwith. */ + heavyAdsNetworkLimitMessage: 'The page contains ads that use ' + + 'more than 4 megabytes of network bandwidth', + /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 60 seconds in total. */ + heavyAdsCPUTotalLimitMessage: 'The page contains ads that use the ' + + 'main thread for more than 60 seconds in total', + /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 15 seconds in any 30 second window. */ + heavyAdsCPUPeakLimitMessage: 'The page contains ads that use the ' + + 'main thread for more than 15 seconds in a 30 second window', + /** Message shown in a data table when the item is a ContentSecurityPolicy issue where resources are blocked due to not being in the Content Security Policy header. */ + cspUrlViolationMessage: 'The CSP of the page blocks some resources because ' + + 'their origin is not included in the content security policy header', + /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks inline execution of scripts and stylesheets. */ + cspInlineViolationMessage: 'The CSP of the page blocks ' + + 'inline execution of scripts and stylesheets', + /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks the use of the `eval` function in Javascript. */ + cspEvalViolationMessage: 'The CSP of the site blocks ' + + 'the use of `eval` in JavaScript', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + +/** @type {Object} */ +const heavyAdsMsgMap = { + 'NetworkTotalLimit': str_(UIStrings.heavyAdsNetworkLimitMessage), + 'CpuTotalLimit': str_(UIStrings.heavyAdsCPUTotalLimitMessage), + 'CpuPeakLimit': str_(UIStrings.heavyAdsCPUPeakLimitMessage), +}; +/** @type {Object} */ +const contentSecurityPolicyMsgMap = { + 'kInlineViolation': str_(UIStrings.cspInlineViolationMessage), + 'kEvalViolation': str_(UIStrings.cspEvalViolationMessage), + 'kURLViolation': str_(UIStrings.cspUrlViolationMessage), +}; /** @type {Object} */ -const issueMap = { - 'sameSiteCookies': str_(UIStrings.sameSiteMsg), - 'mixedContent': str_(UIStrings.mixedContentMsg), - 'blockedByResponse': str_(UIStrings.blockedByResponseMsg), - 'heavyAds': str_(UIStrings.heavyAdsMsg), - 'contentSecurityPolicy': str_(UIStrings.contentSecurityPolicyMsg), +const blockedByResponseMsgMap = { + 'CoepFrameResourceNeedsCoepHeader': str_(UIStrings.coepResourceBlockedMessage), + 'CoopSandboxedIFrameCannotNavigateToCoopPage': str_(UIStrings.coopIframeBlockedMessage), + 'CorpNotSameOrigin': str_(UIStrings.coepResourceBlockedMessage), + 'CorpNotSameOriginAfterDefaultedToSameOriginByCoep': str_(UIStrings.coepFrameBlockedMessage), + 'CorpNotSameSite': str_(UIStrings.coepResourceBlockedMessage), }; -/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ +/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ class IssuesPanelEntries extends Audit { /** @@ -65,7 +100,12 @@ class IssuesPanelEntries extends Audit { } return mixedContentIssues.map(issue => { - + const requestUrl = issue.request && issue.request.url; + return { + issueType: 'MixedContent', + description: str_(UIStrings.mixedContentMessage), + requestUrl: issue.mainResourceURL || requestUrl, + }; }); } @@ -81,9 +121,9 @@ class IssuesPanelEntries extends Audit { return sameSiteCookieIssues.map(issue => { const requestUrl = issue.request && issue.request.url; return { - issueType: 'SameSite Cookie', - description: str_(UIStrings.sameSiteMsg), - requestUrl: requestUrl || issue.cookieUrl, + issueType: 'SameSiteCookie', + description: str_(UIStrings.sameSiteMessage), + requestUrl: issue.cookieUrl || requestUrl, }; }); } @@ -100,8 +140,10 @@ class IssuesPanelEntries extends Audit { return blockedByResponseIssues.map(issue => { const blockedReason = issue.reason; return { - issueType: 'Blocked By Response' - } + issueType: 'BlockedByResponse', + description: blockedByResponseMsgMap[blockedReason], + requestUrl: issue.request.url, + }; }); } @@ -115,7 +157,11 @@ class IssuesPanelEntries extends Audit { } return heavyAdsIssues.map(issue => { - + const reason = issue.reason; + return { + issueType: 'HeavyAds', + description: heavyAdsMsgMap[reason], + }; }); } @@ -128,8 +174,19 @@ class IssuesPanelEntries extends Audit { return []; } - return cspIssues.map(issue => { - + return cspIssues + .filter(issue => { + // kTrustedTypesSinkViolation and kTrustedTypesPolicyViolation aren't currently supported by the Issues panel + return issue.contentSecurityPolicyViolationType !== 'kTrustedTypesSinkViolation' && + issue.contentSecurityPolicyViolationType !== 'kTrustedTypesPolicyViolation'; + }) + .map(issue => { + const blockedUrl = issue.blockedURL; + return { + issueType: 'ContentSecurityPolicy', + description: contentSecurityPolicyMsgMap[issue.contentSecurityPolicyViolationType], + requestUrl: blockedUrl, + }; }); } @@ -150,7 +207,7 @@ class IssuesPanelEntries extends Audit { const items = []; for (const [issueType, issuesOfType] of Object.entries(issues)) { - switch(issueType) { + switch (issueType) { case 'sameSiteCookies': items.push(...this.getSameSiteCookieItems(issuesOfType)); break; From 98a4a44f6bbf938a5b068572e25526abf261548c Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 10 Sep 2020 16:44:38 -0700 Subject: [PATCH 06/23] Update description --- lighthouse-core/audits/dobetterweb/has-inspector-issues.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 0da87b400eb3..850eff227e12 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -14,7 +14,8 @@ const UIStrings = { /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when issues are detected and logged into the devtools Issues panel. */ failureTitle: 'Isssues were logged in the Issues panel', /** Description of a Lighthouse audit that tells the user why issues being logged to the devtools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ - description: 'Description TBD', + description: 'Issues logged to the Issues panel indicate unresolved problems. ' + + 'They can come from network request failures and other browser concerns. ', /** Table column header for the type of issue. */ columnIssueType: 'Issue Type', /** Message shown in a data table when the item is a SameSiteCookie issue. */ From 4152a19686e1bbca8a527dc4b2a5fb62d6dd3952 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Mon, 14 Sep 2020 10:11:41 -0700 Subject: [PATCH 07/23] Apply suggestions from code review Co-authored-by: Connor Clark --- lighthouse-core/audits/dobetterweb/has-inspector-issues.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 850eff227e12..e0e46a81146f 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -9,10 +9,10 @@ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when no issues were logged into the devtools Issues panel. */ + /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when no issues were logged into the Chrome DevTools Issues panel. */ title: 'No issues in the Issues panel', /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when issues are detected and logged into the devtools Issues panel. */ - failureTitle: 'Isssues were logged in the Issues panel', + failureTitle: 'Issues were logged in the Issues panel', /** Description of a Lighthouse audit that tells the user why issues being logged to the devtools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ description: 'Issues logged to the Issues panel indicate unresolved problems. ' + 'They can come from network request failures and other browser concerns. ', @@ -54,7 +54,7 @@ const UIStrings = { const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); -/** @type {Object} */ +/** @type {Record} */ const heavyAdsMsgMap = { 'NetworkTotalLimit': str_(UIStrings.heavyAdsNetworkLimitMessage), 'CpuTotalLimit': str_(UIStrings.heavyAdsCPUTotalLimitMessage), From 55990ea4f0cfa93f27ca2d6f69de45711d419a51 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 17 Sep 2020 18:29:32 -0700 Subject: [PATCH 08/23] String changes and unit test --- .../dobetterweb/has-inspector-issues.js | 45 +++---- lighthouse-core/lib/i18n/locales/ar-XB.json | 3 - lighthouse-core/lib/i18n/locales/ar.json | 3 - lighthouse-core/lib/i18n/locales/bg.json | 3 - lighthouse-core/lib/i18n/locales/ca.json | 3 - lighthouse-core/lib/i18n/locales/cs.json | 3 - lighthouse-core/lib/i18n/locales/da.json | 3 - lighthouse-core/lib/i18n/locales/de.json | 3 - lighthouse-core/lib/i18n/locales/el.json | 3 - lighthouse-core/lib/i18n/locales/en-GB.json | 3 - lighthouse-core/lib/i18n/locales/en-US.json | 51 +++++++- lighthouse-core/lib/i18n/locales/en-XA.json | 3 - lighthouse-core/lib/i18n/locales/en-XL.json | 51 +++++++- lighthouse-core/lib/i18n/locales/es-419.json | 3 - lighthouse-core/lib/i18n/locales/es.json | 3 - lighthouse-core/lib/i18n/locales/fi.json | 3 - lighthouse-core/lib/i18n/locales/fil.json | 3 - lighthouse-core/lib/i18n/locales/fr.json | 3 - lighthouse-core/lib/i18n/locales/he.json | 3 - lighthouse-core/lib/i18n/locales/hi.json | 3 - lighthouse-core/lib/i18n/locales/hr.json | 3 - lighthouse-core/lib/i18n/locales/hu.json | 3 - lighthouse-core/lib/i18n/locales/id.json | 3 - lighthouse-core/lib/i18n/locales/it.json | 3 - lighthouse-core/lib/i18n/locales/ja.json | 3 - lighthouse-core/lib/i18n/locales/ko.json | 3 - lighthouse-core/lib/i18n/locales/lt.json | 3 - lighthouse-core/lib/i18n/locales/lv.json | 3 - lighthouse-core/lib/i18n/locales/nl.json | 3 - lighthouse-core/lib/i18n/locales/no.json | 3 - lighthouse-core/lib/i18n/locales/pl.json | 3 - lighthouse-core/lib/i18n/locales/pt-PT.json | 3 - lighthouse-core/lib/i18n/locales/pt.json | 3 - lighthouse-core/lib/i18n/locales/ro.json | 3 - lighthouse-core/lib/i18n/locales/ru.json | 3 - lighthouse-core/lib/i18n/locales/sk.json | 3 - lighthouse-core/lib/i18n/locales/sl.json | 3 - lighthouse-core/lib/i18n/locales/sr-Latn.json | 3 - lighthouse-core/lib/i18n/locales/sr.json | 3 - lighthouse-core/lib/i18n/locales/sv.json | 3 - lighthouse-core/lib/i18n/locales/ta.json | 3 - lighthouse-core/lib/i18n/locales/te.json | 3 - lighthouse-core/lib/i18n/locales/th.json | 3 - lighthouse-core/lib/i18n/locales/tr.json | 3 - lighthouse-core/lib/i18n/locales/uk.json | 3 - lighthouse-core/lib/i18n/locales/vi.json | 3 - lighthouse-core/lib/i18n/locales/zh-HK.json | 3 - lighthouse-core/lib/i18n/locales/zh-TW.json | 3 - lighthouse-core/lib/i18n/locales/zh.json | 3 - .../has-inspector-issues-test.js.snap | 68 ++++++++++ .../dobetterweb/has-inspector-issues-test.js | 123 ++++++++++++++++++ lighthouse-core/test/results/sample_v2.json | 33 ++++- 52 files changed, 341 insertions(+), 168 deletions(-) create mode 100644 lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap create mode 100644 lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index e0e46a81146f..5c198d9dd97e 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -5,33 +5,36 @@ */ 'use strict'; +/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ + const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when no issues were logged into the Chrome DevTools Issues panel. */ - title: 'No issues in the Issues panel', - /** Title of a Lighthouse audit that provides detail on inspector issues. This descriptive title is shown to users when issues are detected and logged into the devtools Issues panel. */ - failureTitle: 'Issues were logged in the Issues panel', - /** Description of a Lighthouse audit that tells the user why issues being logged to the devtools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ - description: 'Issues logged to the Issues panel indicate unresolved problems. ' + - 'They can come from network request failures and other browser concerns. ', + title: 'No issues in the `Issues` panel in Chrome Devtools', + /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when issues are detected and logged into the Chrome DevTools Issues panel. */ + failureTitle: 'Issues were logged in the `Issues` panel in Chrome Devtools', + /** Description of a Lighthouse audit that tells the user why issues being logged to the Chrome DevTools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ + description: 'Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. ' + + 'They can come from network request failures, insufficient security controls, ' + + ' and other browser concerns. ', /** Table column header for the type of issue. */ - columnIssueType: 'Issue Type', + columnIssueType: 'Issue', /** Message shown in a data table when the item is a SameSiteCookie issue. */ - sameSiteMessage: 'This is a SameSite Cookies issue', + sameSiteMessage: 'A cookie\'s [`SameSite`] attribute was not set or is invalid', /** Message shown in a data table when the item is a MixedContent issue. This is when some resources are loaded over an insecure HTTP connection. */ mixedContentMessage: 'Some resources like images, stylesheets or scripts ' + - 'are being accessed over an insecure HTTP connection', + 'are being accessed over an insecure `HTTP` connection', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a resource is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ coepResourceBlockedMessage: 'A resource was blocked due to not being ' + - 'allowed by a Cross-Origin Embedder Policy', + 'allowed by a `Cross-Origin Embedder Policy`', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a frame is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ coepFrameBlockedMessage: 'A frame was blocked due to not being ' + - 'allowed by a Cross-Origin Embedder Policy', + 'allowed by a `Cross-Origin Embedder Policy`', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when navigation to a document with a Cross-Origin Opener Policy is blocked. */ coopIframeBlockedMessage: 'An iframe navigation to a document with ' + - 'a Cross-Origin Opener Policy was blocked', + 'a `Cross-Origin Opener Policy` was blocked', /** Message shown in a data table when the item is a HeavyAds issue where an ad uses more than 4 megabytes of network bandwith. */ heavyAdsNetworkLimitMessage: 'The page contains ads that use ' + 'more than 4 megabytes of network bandwidth', @@ -42,13 +45,13 @@ const UIStrings = { heavyAdsCPUPeakLimitMessage: 'The page contains ads that use the ' + 'main thread for more than 15 seconds in a 30 second window', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where resources are blocked due to not being in the Content Security Policy header. */ - cspUrlViolationMessage: 'The CSP of the page blocks some resources because ' + + cspUrlViolationMessage: 'The `Content Security Policy` of the page blocks some resources because ' + 'their origin is not included in the content security policy header', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks inline execution of scripts and stylesheets. */ - cspInlineViolationMessage: 'The CSP of the page blocks ' + + cspInlineViolationMessage: 'The `Content Security Policy` of the page blocks ' + 'inline execution of scripts and stylesheets', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks the use of the `eval` function in Javascript. */ - cspEvalViolationMessage: 'The CSP of the site blocks ' + + cspEvalViolationMessage: 'The `Content Security Policy` of the site blocks ' + 'the use of `eval` in JavaScript', }; @@ -75,8 +78,6 @@ const blockedByResponseMsgMap = { 'CorpNotSameSite': str_(UIStrings.coepResourceBlockedMessage), }; -/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ - class IssuesPanelEntries extends Audit { /** * @return {LH.Audit.Meta} @@ -93,7 +94,7 @@ class IssuesPanelEntries extends Audit { /** * @param {Array} mixedContentIssues - * @return {Array} + * @return {Array} */ static getMixedContentItems(mixedContentIssues) { if (!mixedContentIssues) { @@ -112,7 +113,7 @@ class IssuesPanelEntries extends Audit { /** * @param {Array} sameSiteCookieIssues - * @return {Array} + * @return {Array} */ static getSameSiteCookieItems(sameSiteCookieIssues) { if (!sameSiteCookieIssues) { @@ -131,7 +132,7 @@ class IssuesPanelEntries extends Audit { /** * @param {Array} blockedByResponseIssues - * @return {Array} + * @return {Array} */ static getBlockedByResponseItems(blockedByResponseIssues) { if (!blockedByResponseIssues) { @@ -150,7 +151,7 @@ class IssuesPanelEntries extends Audit { /** * @param {Array} heavyAdsIssues - * @return {Array} + * @return {Array} */ static getHeavyAdsItems(heavyAdsIssues) { if (!heavyAdsIssues) { @@ -168,7 +169,7 @@ class IssuesPanelEntries extends Audit { /** * @param {Array} cspIssues - * @return {Array} + * @return {Array} */ static getContentSecurityPolicyItems(cspIssues) { if (!cspIssues) { diff --git a/lighthouse-core/lib/i18n/locales/ar-XB.json b/lighthouse-core/lib/i18n/locales/ar-XB.json index 42ce553ac6a2..4d3c038ab2d1 100644 --- a/lighthouse-core/lib/i18n/locales/ar-XB.json +++ b/lighthouse-core/lib/i18n/locales/ar-XB.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "‏‮Uses‬‏ ‏‮passive‬‏ ‏‮listeners‬‏ ‏‮to‬‏ ‏‮improve‬‏ ‏‮scrolling‬‏ ‏‮performance‬‏" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "‏‮Description‬‏" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "‏‮Errors‬‏ ‏‮logged‬‏ ‏‮to‬‏ ‏‮the‬‏ ‏‮console‬‏ ‏‮indicate‬‏ ‏‮unresolved‬‏ ‏‮problems‬‏. ‏‮They‬‏ ‏‮can‬‏ ‏‮come‬‏ ‏‮from‬‏ ‏‮network‬‏ ‏‮request‬‏ ‏‮failures‬‏ ‏‮and‬‏ ‏‮other‬‏ ‏‮browser‬‏ ‏‮concerns‬‏. [‏‮Learn‬‏ ‏‮more‬‏](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ar.json b/lighthouse-core/lib/i18n/locales/ar.json index 18c014c70b33..716546416793 100644 --- a/lighthouse-core/lib/i18n/locales/ar.json +++ b/lighthouse-core/lib/i18n/locales/ar.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "يتم استخدام أدوات معالجة الحدث السلبية لتحسين أداء التمرير" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "الوصف" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "تشير الأخطاء التي تم تسجيلها في وحدة التحكّم إلى مشاكل لم يتم حلها. قد تنتج هذه المشاكل من إخفاقات طلب الشبكة ومشاكل أخرى تتعلق بالمتصفّح. [مزيد من المعلومات](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/bg.json b/lighthouse-core/lib/i18n/locales/bg.json index be7ba993d5a7..052460085a98 100644 --- a/lighthouse-core/lib/i18n/locales/bg.json +++ b/lighthouse-core/lib/i18n/locales/bg.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Използва пасивни приематели на събития за подобряване на ефективността при превъртане" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Описание" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Грешките, записани в конзолата, показват нерешени проблеми. Те може да се дължат на неуспешни заявки за мрежата и други проблеми в браузъра. [Научете повече](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ca.json b/lighthouse-core/lib/i18n/locales/ca.json index 2fe12bf73d8e..7233ee3fb9fd 100644 --- a/lighthouse-core/lib/i18n/locales/ca.json +++ b/lighthouse-core/lib/i18n/locales/ca.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Utilitza detectors passius per millorar el rendiment del desplaçament" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descripció" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Els errors registrats a la consola indiquen problemes pendents de resoldre. Poden provenir d'errors de sol·licitud de la xarxa i d'altres problemes del navegador. [Més informació](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/cs.json b/lighthouse-core/lib/i18n/locales/cs.json index 725fac4723e6..3650a8c8b924 100644 --- a/lighthouse-core/lib/i18n/locales/cs.json +++ b/lighthouse-core/lib/i18n/locales/cs.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Používá pasivní posluchače, které zlepšují posouvání" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Popis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Chyby zaprotokolované do konzole ukazují na nevyřešené problémy. Mohou pocházet ze selhání síťových požadavků nebo jiných problémů v prohlížeči. [Další informace](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/da.json b/lighthouse-core/lib/i18n/locales/da.json index 3a9f1cffb2f2..5a41643ccf0e 100644 --- a/lighthouse-core/lib/i18n/locales/da.json +++ b/lighthouse-core/lib/i18n/locales/da.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Anvender passive hændelsesfunktioner til at forbedre rulning" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Beskrivelse" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Fejl, der er logført i konsollen, angiver uløste problemer. De kan stamme fra mislykkede netværksanmodninger og andre browserproblemer. [Få flere oplysninger](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json index d019189fe257..350ac36ef5b4 100644 --- a/lighthouse-core/lib/i18n/locales/de.json +++ b/lighthouse-core/lib/i18n/locales/de.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Verwendet passive Listener zur Verbesserung der Scrollleistung" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Beschreibung" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "In der Konsole protokollierte Fehler weisen auf ungelöste Probleme hin. Sie können durch fehlgeschlagene Netzwerkanfragen und andere Browser-Probleme verursacht werden. [Weitere Informationen](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/el.json b/lighthouse-core/lib/i18n/locales/el.json index 139000f0edd8..97caa12a8b58 100644 --- a/lighthouse-core/lib/i18n/locales/el.json +++ b/lighthouse-core/lib/i18n/locales/el.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Χρησιμοποιεί παθητικές λειτουργίες επεξεργασίας συμβάντων για τη βελτίωση της απόδοσης κύλισης" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Περιγραφή" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Τα σφάλματα που έχουν καταγραφεί στην κονσόλα υποδεικνύουν ότι υπάρχουν προβλήματα τα οποία δεν έχουν επιλυθεί. Μπορεί να σχετίζονται με σφάλματα αιτημάτων δικτύου ή με άλλα ζητήματα του προγράμματος περιήγησης. [Μάθετε περισσότερα](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/en-GB.json b/lighthouse-core/lib/i18n/locales/en-GB.json index 64e6ea524ad8..897e838ba587 100644 --- a/lighthouse-core/lib/i18n/locales/en-GB.json +++ b/lighthouse-core/lib/i18n/locales/en-GB.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Uses passive listeners to improve scrolling performance" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Description" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Errors logged to the console indicate unresolved problems. They can come from network request failures and other browser concerns. [Learn more](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 4a32fbab2907..9191e5d0c562 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -665,6 +665,51 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Avoids requesting the geolocation permission on page load" }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage": { + "message": "A frame was blocked due to not being allowed by a `Cross-Origin Embedder Policy`" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage": { + "message": "A resource was blocked due to not being allowed by a `Cross-Origin Embedder Policy`" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | columnIssueType": { + "message": "Issue" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage": { + "message": "An iframe navigation to a document with a `Cross-Origin Opener Policy` was blocked" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage": { + "message": "The `Content Security Policy` of the site blocks the use of `eval` in JavaScript" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage": { + "message": "The `Content Security Policy` of the page blocks inline execution of scripts and stylesheets" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage": { + "message": "The `Content Security Policy` of the page blocks some resources because their origin is not included in the content security policy header" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | description": { + "message": "Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. " + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | failureTitle": { + "message": "Issues were logged in the `Issues` panel in Chrome Devtools" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage": { + "message": "The page contains ads that use the main thread for more than 15 seconds in a 30 second window" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage": { + "message": "The page contains ads that use the main thread for more than 60 seconds in total" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage": { + "message": "The page contains ads that use more than 4 megabytes of network bandwidth" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage": { + "message": "Some resources like images, stylesheets or scripts are being accessed over an insecure `HTTP` connection" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage": { + "message": "A cookie's [`SameSite`] attribute was not set or is invalid" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | title": { + "message": "No issues in the `Issues` panel in Chrome Devtools" + }, "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { "message": "Version" }, @@ -752,9 +797,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Uses passive listeners to improve scrolling performance" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Description" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Errors logged to the console indicate unresolved problems. They can come from network request failures and other browser concerns. [Learn more](https://web.dev/errors-in-console/)" }, @@ -1607,6 +1649,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnCacheTTL": { "message": "Cache TTL" }, + "lighthouse-core/lib/i18n/i18n.js | columnDescription": { + "message": "Description" + }, "lighthouse-core/lib/i18n/i18n.js | columnDuration": { "message": "Duration" }, diff --git a/lighthouse-core/lib/i18n/locales/en-XA.json b/lighthouse-core/lib/i18n/locales/en-XA.json index a3fb61c6f7ce..1e775f4d7b3a 100644 --- a/lighthouse-core/lib/i18n/locales/en-XA.json +++ b/lighthouse-core/lib/i18n/locales/en-XA.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "[Ûšéš þåššîvé ļîšţéñéŕš ţö îmþŕövé šçŕöļļîñĝ þéŕƒöŕmåñçé one two three four five six seven eight nine ten eleven]" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "[Ðéšçŕîþţîöñ one two]" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "[Éŕŕöŕš ļöĝĝéð ţö ţĥé çöñšöļé îñðîçåţé ûñŕéšöļvéð þŕöбļémš. Ţĥéý çåñ çömé ƒŕöm ñéţŵöŕķ ŕéqûéšţ ƒåîļûŕéš åñð öţĥéŕ бŕöŵšéŕ çöñçéŕñš. ᐅ[ᐊĻéåŕñ möŕéᐅ](https://web.dev/errors-in-console/)ᐊ one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone twentytwo]" }, diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 58931c6cda05..f1cfaa95b8d1 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -665,6 +665,51 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Âv́ôíd̂ś r̂éq̂úêśt̂ín̂ǵ t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage": { + "message": " f́r̂ám̂é ŵáŝ b́l̂óĉḱêd́ d̂úê t́ô ńôt́ b̂éîńĝ ál̂ĺôẃêd́ b̂ý â `Cross-Origin Embedder Policy`" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage": { + "message": " ŕêśôúr̂ćê ẃâś b̂ĺôćk̂éd̂ d́ûé t̂ó n̂ót̂ b́êín̂ǵ âĺl̂óŵéd̂ b́ŷ á `Cross-Origin Embedder Policy`" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | columnIssueType": { + "message": "Îśŝúê" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage": { + "message": "Âń îf́r̂ám̂é n̂áv̂íĝát̂íôń t̂ó â d́ôćûḿêńt̂ ẃît́ĥ á `Cross-Origin Opener Policy` ŵáŝ b́l̂óĉḱêd́" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage": { + "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé ŝít̂é b̂ĺôćk̂ś t̂h́ê úŝé ôf́ `eval` îń Ĵáv̂áŜćr̂íp̂t́" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage": { + "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé p̂áĝé b̂ĺôćk̂ś îńl̂ín̂é êx́êćût́îón̂ óf̂ śĉŕîṕt̂ś âńd̂ śt̂ýl̂éŝh́êét̂ś" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage": { + "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé p̂áĝé b̂ĺôćk̂ś ŝóm̂é r̂éŝóûŕĉéŝ b́êćâúŝé t̂h́êír̂ ór̂íĝín̂ íŝ ńôt́ îńĉĺûd́êd́ îń t̂h́ê ćôńt̂én̂t́ ŝéĉúr̂ít̂ý p̂ól̂íĉý ĥéâd́êŕ" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | description": { + "message": "Îśŝúêś l̂óĝǵêd́ t̂ó t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś îńd̂íĉát̂é ûńr̂éŝól̂v́êd́ p̂ŕôb́l̂ém̂ś. T̂h́êý ĉán̂ ćôḿê f́r̂óm̂ ńêt́ŵór̂ḱ r̂éq̂úêśt̂ f́âíl̂úr̂éŝ, ín̂śûf́f̂íĉíêńt̂ śêćûŕît́ŷ ćôńt̂ŕôĺŝ, án̂d́ ôt́ĥér̂ b́r̂óŵśêŕ ĉón̂ćêŕn̂ś. " + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | failureTitle": { + "message": "Îśŝúêś ŵér̂é l̂óĝǵêd́ îń t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage": { + "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê t́ĥé m̂áîń t̂h́r̂éâd́ f̂ór̂ ḿôŕê t́ĥán̂ 15 śêćôńd̂ś îń â 30 śêćôńd̂ ẃîńd̂óŵ" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage": { + "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê t́ĥé m̂áîń t̂h́r̂éâd́ f̂ór̂ ḿôŕê t́ĥán̂ 60 śêćôńd̂ś îń t̂ót̂ál̂" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage": { + "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê ḿôŕê t́ĥán̂ 4 ḿêǵâb́ŷt́êś ôf́ n̂ét̂ẃôŕk̂ b́âńd̂ẃîd́t̂h́" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage": { + "message": "Ŝóm̂é r̂éŝóûŕĉéŝ ĺîḱê ím̂áĝéŝ, śt̂ýl̂éŝh́êét̂ś ôŕ ŝćr̂íp̂t́ŝ ár̂é b̂éîńĝ áĉćêśŝéd̂ óv̂ér̂ án̂ ín̂śêćûŕê `HTTP` ćôńn̂éĉt́îón̂" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage": { + "message": " ćôók̂íê'ś [`SameSite`] ât́t̂ŕîb́ût́ê ẃâś n̂ót̂ śêt́ ôŕ îś îńv̂ál̂íd̂" + }, + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | title": { + "message": "N̂ó îśŝúêś îń t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś" + }, "lighthouse-core/audits/dobetterweb/js-libraries.js | columnVersion": { "message": "V̂ér̂śîón̂" }, @@ -752,9 +797,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Ûśêś p̂áŝśîv́ê ĺîśt̂én̂ér̂ś t̂ó îḿp̂ŕôv́ê śĉŕôĺl̂ín̂ǵ p̂ér̂f́ôŕm̂án̂ćê" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "D̂éŝćr̂íp̂t́îón̂" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Êŕr̂ór̂ś l̂óĝǵêd́ t̂ó t̂h́ê ćôńŝól̂é îńd̂íĉát̂é ûńr̂éŝól̂v́êd́ p̂ŕôb́l̂ém̂ś. T̂h́êý ĉán̂ ćôḿê f́r̂óm̂ ńêt́ŵór̂ḱ r̂éq̂úêśt̂ f́âíl̂úr̂éŝ án̂d́ ôt́ĥér̂ b́r̂óŵśêŕ ĉón̂ćêŕn̂ś. [L̂éâŕn̂ ḿôŕê](https://web.dev/errors-in-console/)" }, @@ -1607,6 +1649,9 @@ "lighthouse-core/lib/i18n/i18n.js | columnCacheTTL": { "message": "Ĉáĉh́ê T́T̂Ĺ" }, + "lighthouse-core/lib/i18n/i18n.js | columnDescription": { + "message": "D̂éŝćr̂íp̂t́îón̂" + }, "lighthouse-core/lib/i18n/i18n.js | columnDuration": { "message": "D̂úr̂át̂íôń" }, diff --git a/lighthouse-core/lib/i18n/locales/es-419.json b/lighthouse-core/lib/i18n/locales/es-419.json index 6e4c17fd37cd..6b983a4b4456 100644 --- a/lighthouse-core/lib/i18n/locales/es-419.json +++ b/lighthouse-core/lib/i18n/locales/es-419.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Usa objetos de escucha pasivos para mejorar el rendimiento del desplazamiento" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descripción" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Los errores registrados en la consola indican la existencia de problemas no resueltos. Es posible que se deban a problemas con solicitudes de red y otros relativos al navegador. [Obtén más información](https://web.dev/errors-in-console/)." }, diff --git a/lighthouse-core/lib/i18n/locales/es.json b/lighthouse-core/lib/i18n/locales/es.json index c88ff8f3a91a..20f2f341ad96 100644 --- a/lighthouse-core/lib/i18n/locales/es.json +++ b/lighthouse-core/lib/i18n/locales/es.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Usa listeners pasivos para mejorar el desplazamiento" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descripción" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Los errores registrados en la consola indican que hay problemas sin resolver. Pueden proceder de solicitudes fallidas de la red y otros errores del navegador. [Más información](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/fi.json b/lighthouse-core/lib/i18n/locales/fi.json index b2d120a333f1..84738b2da0c8 100644 --- a/lighthouse-core/lib/i18n/locales/fi.json +++ b/lighthouse-core/lib/i18n/locales/fi.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Käyttää passiivisia seuraimia vieritystoiminnan parantamiseen" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Kuvaus" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Konsoliin kirjatut virheet viittaavat ratkaisemattomiin ongelmiin. Ne voivat johtua epäonnistuneista verkkopyynnöistä ja muista selainongelmista. [Lue lisää](https://web.dev/errors-in-console/)." }, diff --git a/lighthouse-core/lib/i18n/locales/fil.json b/lighthouse-core/lib/i18n/locales/fil.json index b9eee2e6357c..38654bdd54a7 100644 --- a/lighthouse-core/lib/i18n/locales/fil.json +++ b/lighthouse-core/lib/i18n/locales/fil.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Gumagamit ng mga passive na listener para pahusayin ang performance sa pag-scroll" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Paglalarawan" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Nagsasaad ng mga hindi naresolbang problema ang mga error na naka-log sa console. Puwedeng manggaling ang mga ito sa mga hindi nagawang kahilingan sa network at iba pang alalahanin sa browser. [Matuto pa](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/fr.json b/lighthouse-core/lib/i18n/locales/fr.json index 806c87cc77a9..b1ad63e750e7 100644 --- a/lighthouse-core/lib/i18n/locales/fr.json +++ b/lighthouse-core/lib/i18n/locales/fr.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "La page utilise des écouteurs d'événements passifs pour améliorer les performances de défilement" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Description" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Les erreurs enregistrées dans la console indiquent des problèmes non résolus. Ces derniers peuvent être dus à des requêtes réseau qui ont échoué et à d'autres problèmes du navigateur. [En savoir plus](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/he.json b/lighthouse-core/lib/i18n/locales/he.json index 91a7e1555aac..091a04134030 100644 --- a/lighthouse-core/lib/i18n/locales/he.json +++ b/lighthouse-core/lib/i18n/locales/he.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "נעשה שימוש ברכיבי listener פסיביים לשיפור ביצועי הגלילה" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "תיאור" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "שגיאות שנרשמו במסוף מצביעות על בעיות לא פתורות. הן עשויות להופיע בעקבות כשל בבקשות ברשת או בעיות אחרות בדפדפן. [מידע נוסף](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/hi.json b/lighthouse-core/lib/i18n/locales/hi.json index c93099b5a1c8..c64c74a1a986 100644 --- a/lighthouse-core/lib/i18n/locales/hi.json +++ b/lighthouse-core/lib/i18n/locales/hi.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "पैसिव श्रोताओं की मदद से स्क्रोल परफ़ॉर्मेंस बेहतर की जाती है" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "ब्यौरा" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "कंसोल में लॉग की गई गड़बड़ियां उन मुश्किलों की तरफ़ इशारा करती हैं जिनका समाधान किया जाना अभी बाकी है. ये गड़बड़ियां, नेटवर्क अनुरोधों के काम न करने और ब्राउज़र से जुड़ी दूसरी वजहों से हो सकती हैं. [ज़्यादा जानें](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/hr.json b/lighthouse-core/lib/i18n/locales/hr.json index c7a0f0904283..9e69598b3215 100644 --- a/lighthouse-core/lib/i18n/locales/hr.json +++ b/lighthouse-core/lib/i18n/locales/hr.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Upotrebljava pasivne osluškivače za unaprjeđenje rezultata pretraživanja" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Opis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Pogreške zabilježene u konzoli ukazuju na neriješene probleme. Rezultat su neuspjelih mrežnih zahtjeva i ostalih pitanja povezanih s preglednikom. [Saznajte više](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/hu.json b/lighthouse-core/lib/i18n/locales/hu.json index d8f637ff2651..970216326186 100644 --- a/lighthouse-core/lib/i18n/locales/hu.json +++ b/lighthouse-core/lib/i18n/locales/hu.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Passzív figyelőket alkalmaz a görgetés teljesítményének javításához" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Leírás" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "A konzolon megjelenő hibák megoldatlan problémákat jeleznek. Okaik lehetnek sikertelen hálózati kérések, valamint más böngészős tényezők is. [További információ](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/id.json b/lighthouse-core/lib/i18n/locales/id.json index 44de054b81d4..9591dcd983eb 100644 --- a/lighthouse-core/lib/i18n/locales/id.json +++ b/lighthouse-core/lib/i18n/locales/id.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Menggunakan pemroses pasif untuk menyempurnakan performa scroll" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Deskripsi" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Error yang dicatat di konsol menunjukkan masalah yang belum terselesaikan. Error dapat berasal dari permintaan jaringan yang gagal dan masalah browser lainnya. [Pelajari lebih lanjut](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/it.json b/lighthouse-core/lib/i18n/locales/it.json index 4a2e2dbb12fb..9d6e79dfeb42 100644 --- a/lighthouse-core/lib/i18n/locales/it.json +++ b/lighthouse-core/lib/i18n/locales/it.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Usa listener passivi per migliorare le prestazioni dello scorrimento" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descrizione" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Gli errori registrati nella console indicano la presenza di problemi irrisolti che potrebbero riguardare richieste di rete non andate a buon fine e altri problemi del browser. [Ulteriori informazioni](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ja.json b/lighthouse-core/lib/i18n/locales/ja.json index 77abae5df085..b5b8ff5ad79a 100644 --- a/lighthouse-core/lib/i18n/locales/ja.json +++ b/lighthouse-core/lib/i18n/locales/ja.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "スクロール パフォーマンスを高める受動的なリスナーが使用されています" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "説明" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "コンソールに記録されたエラーは未解決の問題を表します。これらはネットワーク リクエストの失敗や他のブラウザの問題が原因で表示される可能性があります。[詳細](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ko.json b/lighthouse-core/lib/i18n/locales/ko.json index e8f23a4e6f4f..99ea7ffb96a3 100644 --- a/lighthouse-core/lib/i18n/locales/ko.json +++ b/lighthouse-core/lib/i18n/locales/ko.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "스크롤 성능 개선에 패시브 리스너 사용" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "설명" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "콘솔에 로그된 오류는 해결되지 않은 문제를 의미합니다. 네트워크 요청 실패를 비롯한 기타 브라우저 문제로 인해 발생할 수 있습니다. [자세히 알아보기](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/lt.json b/lighthouse-core/lib/i18n/locales/lt.json index 863d073408b0..28cc58a427d6 100644 --- a/lighthouse-core/lib/i18n/locales/lt.json +++ b/lighthouse-core/lib/i18n/locales/lt.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Naudojamos pasyvios apdorojimo priemonės siekiant pagerinti slinkimo našumą" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Aprašas" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Pulte užregistruotos klaidos nurodo, kad esama neišspręstų problemų. Jos galėjo kilti nepavykus pateikti tinklo užklausų arba dėl kitų naršyklės problemų. [Sužinokite daugiau](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/lv.json b/lighthouse-core/lib/i18n/locales/lv.json index d3f26e771c8f..7df7fc6abf69 100644 --- a/lighthouse-core/lib/i18n/locales/lv.json +++ b/lighthouse-core/lib/i18n/locales/lv.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Tiek izmantoti pasīvie klausītāji, lai uzlabotu ritināšanas veiktspēju" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Apraksts" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Konsolē reģistrētās kļūdas norāda uz neatrisinātām problēmām. Tās var rasties no tīkla pieprasījuma kļūmēm un citām pārlūkprogrammas problēmām. [Uzzināt vairāk](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/nl.json b/lighthouse-core/lib/i18n/locales/nl.json index ac9dd11e5b0e..aa3be5896a27 100644 --- a/lighthouse-core/lib/i18n/locales/nl.json +++ b/lighthouse-core/lib/i18n/locales/nl.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Gebruikt passieve listeners voor de verbetering van de scrollprestaties" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Beschrijving" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Fouten die op de console worden geregistreerd, geven aan dat er onopgeloste problemen zijn. Ze kunnen afkomstig zijn van niet-uitgevoerde netwerkverzoeken en andere problemen met de browser. [Meer informatie](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/no.json b/lighthouse-core/lib/i18n/locales/no.json index e834cc4743bb..8798bd19d434 100644 --- a/lighthouse-core/lib/i18n/locales/no.json +++ b/lighthouse-core/lib/i18n/locales/no.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Bruker passive lyttere for å oppnå bedre ytelse ved rulling på siden" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Beskrivelse" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Feil som loggføres i konsollen, tyder på uløste problemer. De kan stamme fra mislykkede nettverksforespørsler og andre nettleserproblemer. [Finn ut mer](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/pl.json b/lighthouse-core/lib/i18n/locales/pl.json index 2ed496b4be8a..ab061ab28023 100644 --- a/lighthouse-core/lib/i18n/locales/pl.json +++ b/lighthouse-core/lib/i18n/locales/pl.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Używa detektorów pasywnych do poprawy działania przewijania" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Opis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Błędy zarejestrowane w konsoli wskazują na nierozwiązane problemy. Mogą być spowodowane nieudanymi żądaniami sieciowymi i innymi problemami w przeglądarce. [Więcej informacji](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/pt-PT.json b/lighthouse-core/lib/i18n/locales/pt-PT.json index f1b1504e5c4d..ee1cdd35db69 100644 --- a/lighthouse-core/lib/i18n/locales/pt-PT.json +++ b/lighthouse-core/lib/i18n/locales/pt-PT.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Utiliza ouvintes passivos para melhorar o desempenho do deslocamento" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descrição" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Os erros registados na consola indicam problemas não resolvidos. Estes podem ser provenientes de falhas de pedidos de rede e outras questões do navegador. [Saiba mais](https://web.dev/errors-in-console/)." }, diff --git a/lighthouse-core/lib/i18n/locales/pt.json b/lighthouse-core/lib/i18n/locales/pt.json index 4b6e5e30df88..542d2d50eca4 100644 --- a/lighthouse-core/lib/i18n/locales/pt.json +++ b/lighthouse-core/lib/i18n/locales/pt.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Utiliza listeners passivos para melhorar o desempenho de rolagem" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descrição" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Os erros registrados no console indicam problemas não resolvidos. Eles podem ocorrer devido a falhas de solicitação de rede e outras questões relacionadas ao navegador. [Saiba mais](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ro.json b/lighthouse-core/lib/i18n/locales/ro.json index 459d247d298d..437dc75b0ded 100644 --- a/lighthouse-core/lib/i18n/locales/ro.json +++ b/lighthouse-core/lib/i18n/locales/ro.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Folosește ascultători pasivi pentru a îmbunătăți performanța la derulare" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Descriere" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Erorile înregistrate pe consolă indică probleme nerezolvate Acestea pot fi provocate de erorile de solicitare din rețea și de alte probleme ale browserului. [Află mai multe](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ru.json b/lighthouse-core/lib/i18n/locales/ru.json index bb26ab0bd615..67990dd9b0a1 100644 --- a/lighthouse-core/lib/i18n/locales/ru.json +++ b/lighthouse-core/lib/i18n/locales/ru.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Пассивные прослушиватели событий используются для улучшения производительности при прокрутке" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Описание" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Ошибки, записанные в журнале консоли, указывают на нерешенные проблемы. Это могут быть невыполненные сетевые запросы и другие сбои в работе браузера. [Подробнее…](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sk.json b/lighthouse-core/lib/i18n/locales/sk.json index 51f5476a5590..a4d0ea8965ee 100644 --- a/lighthouse-core/lib/i18n/locales/sk.json +++ b/lighthouse-core/lib/i18n/locales/sk.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Používa pasívne prijímače na zlepšenie posúvania" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Popis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Chyby zapísané do denníka konzoly označujú nevyriešené problémy. Môžu pochádzať zo zlyhaní žiadostí siete a ďalších problémov prehliadača. [Ďalšie informácie](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sl.json b/lighthouse-core/lib/i18n/locales/sl.json index a0717277b3ed..40d89f74fbaf 100644 --- a/lighthouse-core/lib/i18n/locales/sl.json +++ b/lighthouse-core/lib/i18n/locales/sl.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Uporablja pasivne poslušalce za izboljšanje delovanja pomikanja" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Opis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Napake, zabeležene v konzoli, označujejo nerazrešene težave. Te so lahko posledica neuspešnih omrežnih zahtev in drugih težav z brskalnikom. [Več o tem](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sr-Latn.json b/lighthouse-core/lib/i18n/locales/sr-Latn.json index c9bd18b06121..b32f67bda62b 100644 --- a/lighthouse-core/lib/i18n/locales/sr-Latn.json +++ b/lighthouse-core/lib/i18n/locales/sr-Latn.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Koristite pasivne obrađivače da biste poboljšali učinak pomeranja" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Opis" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Greške evidentirane u konzoli ukazuju na nerešene probleme. One su rezultat neuspelih mrežnih zahteva i drugih problema u vezi sa pregledačem. [Saznajte više](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sr.json b/lighthouse-core/lib/i18n/locales/sr.json index cd5ec998db55..0ba2d74d8c42 100644 --- a/lighthouse-core/lib/i18n/locales/sr.json +++ b/lighthouse-core/lib/i18n/locales/sr.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Користите пасивне обрађиваче да бисте побољшали учинак померања" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Опис" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Грешке евидентиране у конзоли указују на нерешене проблеме. Оне су резултат неуспелих мрежних захтева и других проблема у вези са прегледачем. [Сазнајте више](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/sv.json b/lighthouse-core/lib/i18n/locales/sv.json index 9c681473a754..7c744c554af4 100644 --- a/lighthouse-core/lib/i18n/locales/sv.json +++ b/lighthouse-core/lib/i18n/locales/sv.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Passiva lyssnare används för att förbättra rullningsprestanda" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Beskrivning" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Fel som loggats i konsolen indikerar olösta problem. De kan bero på fel i nätverksförfrågningar och andra webbläsarproblem. [Läs mer](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/ta.json b/lighthouse-core/lib/i18n/locales/ta.json index f5f80c11d565..f9da52d9ae59 100644 --- a/lighthouse-core/lib/i18n/locales/ta.json +++ b/lighthouse-core/lib/i18n/locales/ta.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "நகர்த்துதல் செயல்திறனை மேம்படுத்துவதற்காக பேசிவ் லிசனர்களைப் பயன்படுத்துகின்றன" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "விளக்கம்" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "கன்சோலில் பதிவுசெய்யப்பட்ட பிழைகள் தீர்க்கப்படாத சிக்கல்களைக் குறிக்கின்றன. அவை நெட்வொர்க் கோரிக்கை பிழைகளினாலும் வேறு உலாவி சிக்கல்களினாலும் ஏற்பட்டிருக்கும். [மேலும் அறிக](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/te.json b/lighthouse-core/lib/i18n/locales/te.json index 6cdf3b5e5a2e..7237f0dbc8d2 100644 --- a/lighthouse-core/lib/i18n/locales/te.json +++ b/lighthouse-core/lib/i18n/locales/te.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "స్క్రోలింగ్ పనితీరును మెరుగుపరచడానికి పాసివ్ లిజనర్‌లను వినియోగిస్తుంది" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "వివరణ" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "కన్సోల్‌లో లాగ్ చేయబడిన ఎర్రర్‌లు పరిష్కారం కాని సమస్యలను సూచిస్తాయి. నెట్‌వర్క్ అభ్యర్థన వైఫల్యాలు, ఇతర బ్రౌజర్ ఇబ్బందుల వలన అవి ఏర్పడి ఉంటాయి. [మరింత తెలుసుకోండి](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/th.json b/lighthouse-core/lib/i18n/locales/th.json index 3629c66ec45e..91eb63818879 100644 --- a/lighthouse-core/lib/i18n/locales/th.json +++ b/lighthouse-core/lib/i18n/locales/th.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "ใช้ Listener แบบแพสซีฟเพื่อปรับปรุงประสิทธิภาพการเลื่อน" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "รายละเอียด" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "ข้อผิดพลาดที่บันทึกลงในคอนโซลแสดงให้เห็นถึงปัญหาที่ไม่ได้รับการแก้ไข ข้อผิดพลาดอาจมาจากคำขอเครือข่ายที่ไม่สำเร็จ และปัญหาอื่นๆ เกี่ยวกับเบราว์เซอร์ [ดูข้อมูลเพิ่มเติม](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/tr.json b/lighthouse-core/lib/i18n/locales/tr.json index f358e18c1ff0..c1be8659bcaf 100644 --- a/lighthouse-core/lib/i18n/locales/tr.json +++ b/lighthouse-core/lib/i18n/locales/tr.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Kaydırma performansını artırmak için pasif işleyicileri kullanıyor" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Açıklama" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Konsola kaydedilen hatalar çözülmemiş problemleri belirtir Bunlar, ağ istek hatalarından ve diğer tarayıcı sorunlarından gelebilir. [Daha fazla bilgi](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/uk.json b/lighthouse-core/lib/i18n/locales/uk.json index 983db44a6365..e4d9fb721096 100644 --- a/lighthouse-core/lib/i18n/locales/uk.json +++ b/lighthouse-core/lib/i18n/locales/uk.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Використовує пасивні прослуховувачі, щоб покращити прокручування сторінки" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Опис" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Помилки, записані в журнал консолі, указують на невирішені проблеми. Вони можуть бути викликані збоями запитів мережі або іншими проблемами веб-переглядача. [Докладніше](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/vi.json b/lighthouse-core/lib/i18n/locales/vi.json index 8870c5d4ac9e..b2c981a29395 100644 --- a/lighthouse-core/lib/i18n/locales/vi.json +++ b/lighthouse-core/lib/i18n/locales/vi.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "Sử dụng trình nghe bị động để cải thiện hiệu suất cuộn" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "Nội dung mô tả" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "Các lỗi được ghi vào bảng điều khiển là những sự cố chưa giải quyết. Những sự cố này có thể do lỗi yêu cầu mạng và các vấn đề khác của trình duyệt gây ra. [Tìm hiểu thêm](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/zh-HK.json b/lighthouse-core/lib/i18n/locales/zh-HK.json index 40d5aae7537f..92166534d566 100644 --- a/lighthouse-core/lib/i18n/locales/zh-HK.json +++ b/lighthouse-core/lib/i18n/locales/zh-HK.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "使用被動活動監聽器來提升捲動效能" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "說明" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "如果管理中心有錯誤記錄,表示系統仍有問題尚待解決,例如網絡要求錯誤和其他瀏覽器問題。[瞭解詳情](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/zh-TW.json b/lighthouse-core/lib/i18n/locales/zh-TW.json index f6c1bbbb3a16..d95361068f81 100644 --- a/lighthouse-core/lib/i18n/locales/zh-TW.json +++ b/lighthouse-core/lib/i18n/locales/zh-TW.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "使用被動事件監聽器來提升捲動效能" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "說明" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "如果主控台有錯誤記錄,表示系統有問題尚待解決,例如網路要求錯誤和其他瀏覽器問題。[瞭解詳情](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/lib/i18n/locales/zh.json b/lighthouse-core/lib/i18n/locales/zh.json index da1227b7c76d..a95fbd5b870e 100644 --- a/lighthouse-core/lib/i18n/locales/zh.json +++ b/lighthouse-core/lib/i18n/locales/zh.json @@ -752,9 +752,6 @@ "lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js | title": { "message": "使用被动式监听器来提高滚动性能" }, - "lighthouse-core/audits/errors-in-console.js | columnDesc": { - "message": "说明" - }, "lighthouse-core/audits/errors-in-console.js | description": { "message": "控制台中记录的错误表明有未解决的问题。导致这些错误的可能原因是网络请求失败和其他浏览器问题。[了解详情](https://web.dev/errors-in-console/)" }, diff --git a/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap b/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap new file mode 100644 index 000000000000..b54a221511f2 --- /dev/null +++ b/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap @@ -0,0 +1,68 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Has inspector issues audit lists the correct description with the associated issue type 1`] = ` +Array [ + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage # 0", + "issueType": "MixedContent", + "requestUrl": "www.mixedcontent.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage # 0", + "issueType": "SameSiteCookie", + "requestUrl": "www.samesitecookies.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "issueType": "BlockedByResponse", + "requestUrl": "www.blockedbyresponse.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage # 0", + "issueType": "BlockedByResponse", + "requestUrl": "www.blockedbyresponse.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage # 0", + "issueType": "BlockedByResponse", + "requestUrl": "www.blockedbyresponse.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "issueType": "BlockedByResponse", + "requestUrl": "www.blockedbyresponse.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "issueType": "BlockedByResponse", + "requestUrl": "www.blockedbyresponse.com", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage # 0", + "issueType": "HeavyAds", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage # 0", + "issueType": "HeavyAds", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage # 0", + "issueType": "HeavyAds", + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage # 0", + "issueType": "ContentSecurityPolicy", + "requestUrl": undefined, + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage # 0", + "issueType": "ContentSecurityPolicy", + "requestUrl": undefined, + }, + Object { + "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage # 0", + "issueType": "ContentSecurityPolicy", + "requestUrl": undefined, + }, +] +`; diff --git a/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js b/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js new file mode 100644 index 000000000000..9d5297cd70ff --- /dev/null +++ b/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js @@ -0,0 +1,123 @@ +/** + * @license Copyright 2020 The Lighthouse Authors. 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 InspectorIssuesAudit = + require('../../../audits/dobetterweb/has-inspector-issues.js'); + +/* eslint-env jest */ + +describe('Has inspector issues audit', () => { + it('passes when no issues are found', () => { + const issues = { + /** @type {Array} */ + mixedContent: [], + /** @type {Array} */ + sameSiteCookies: [], + /** @type {Array} */ + blockedByResponse: [], + /** @type {Array} */ + heavyAds: [], + /** @type {Array} */ + contentSecurityPolicy: [], + }; + const auditResult = InspectorIssuesAudit.audit({ + InspectorIssues: issues, + }); + expect(auditResult.score).toBe(1); + expect(auditResult.details.items).toHaveLength(0); + }); + + it('lists the correct description with the associated issue type', () => { + const issues = { + mixedContent: [ + { + resolutionStatus: 'MixedContentBlocked', + insecureURL: 'www.mixedcontent.com', + mainResourceURL: 'www.mixedcontent.com', + }, + ], + sameSiteCookies: [ + { + cookieUrl: 'www.samesitecookies.com', + }, + ], + blockedByResponse: [ + { + reason: 'CoepFrameResourceNeedsCoepHeader', + request: { + url: 'www.blockedbyresponse.com', + }, + }, + { + reason: 'CoopSandboxedIFrameCannotNavigateToCoopPage', + request: { + url: 'www.blockedbyresponse.com', + }, + }, + { + reason: 'CorpNotSameOriginAfterDefaultedToSameOriginByCoep', + request: { + url: 'www.blockedbyresponse.com', + }, + }, + { + reason: 'CorpNotSameOrigin', + request: { + url: 'www.blockedbyresponse.com', + }, + }, + { + reason: 'CorpNotSameSite', + request: { + url: 'www.blockedbyresponse.com', + }, + }, + ], + heavyAds: [ + { + reason: 'NetworkTotalLimit', + }, + { + reason: 'CpuTotalLimit', + }, + { + reason: 'CpuPeakLimit', + }, + ], + contentSecurityPolicy: [ + { + contentSecurityPolicyViolationType: 'kInlineViolation', + blockedUrl: 'www.contentsecuritypolicy.com', + }, + { + contentSecurityPolicyViolationType: 'kEvalViolation', + blockedUrl: 'www.contentsecuritypolicy.com', + }, + { + contentSecurityPolicyViolationType: 'kURLViolation', + blockedUrl: 'www.contentsecuritypolicy.com', + }, + // These last two should be filtered out as they aren't supported yet + { + contentSecurityPolicyViolationType: 'kTrustedTypesSinkViolation', + blockedUrl: 'www.contentsecuritypolicy.com', + }, + { + contentSecurityPolicyViolationType: 'kTrustedTypesPolicyViolation', + blockedUrl: 'www.contentsecuritypolicy.com', + }, + ], + }; + + const auditResult = InspectorIssuesAudit.audit({ + InspectorIssues: issues, + }); + expect(auditResult.score).toBe(0); + expect(auditResult.details.items).toHaveLength(13); + expect(auditResult.details.items).toMatchSnapshot(); + }); +}); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index 5fef0e2d0bff..348f7b0a0397 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -3745,6 +3745,18 @@ ] } }, + "has-inspector-issues": { + "id": "has-inspector-issues", + "title": "No issues in the `Issues` panel in Chrome Devtools", + "description": "Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. ", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, "no-document-write": { "id": "no-document-write", "title": "Avoid `document.write()`", @@ -5036,10 +5048,15 @@ "id": "valid-source-maps", "weight": 0, "group": "best-practices-general" + }, + { + "id": "has-inspector-issues", + "weight": 1, + "group": "best-practices-general" } ], "id": "best-practices", - "score": 0.07 + "score": 0.13 }, "seo": { "title": "SEO", @@ -6356,6 +6373,12 @@ "duration": 100, "entryType": "measure" }, + { + "startTime": 0, + "name": "lh:audit:has-inspector-issues", + "duration": 100, + "entryType": "measure" + }, { "startTime": 0, "name": "lh:audit:no-document-write", @@ -6752,7 +6775,7 @@ "audits[uses-http2].details.headings[0].label", "audits[uses-passive-event-listeners].details.headings[0].text" ], - "lighthouse-core/audits/errors-in-console.js | columnDesc": [ + "lighthouse-core/lib/i18n/i18n.js | columnDescription": [ "audits[errors-in-console].details.headings[1].text" ], "lighthouse-core/audits/server-response-time.js | title": [ @@ -7737,6 +7760,12 @@ "audits[notification-on-start].details.headings[1].text", "audits[uses-passive-event-listeners].details.headings[1].text" ], + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | title": [ + "audits[has-inspector-issues].title" + ], + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | description": [ + "audits[has-inspector-issues].description" + ], "lighthouse-core/audits/dobetterweb/no-document-write.js | failureTitle": [ "audits[no-document-write].title" ], From 9761b054fdddf6356a64d940fd77dab29d81c8e3 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Thu, 17 Sep 2020 18:34:51 -0700 Subject: [PATCH 09/23] Add fileoverview --- lighthouse-core/audits/dobetterweb/has-inspector-issues.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 5c198d9dd97e..34470cbdd0b8 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -3,6 +3,13 @@ * 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. */ + + /** + * @fileoverview Audits a page to determine whether it generates issues in the Issues panel of Chrome Devtools. + * The audit is meant to maintain parity with the Chrome Devtools Issues panel front end. + * https://source.chromium.org/chromium/chromium/src/+/master:third_party/devtools-frontend/src/front_end/sdk/ + */ + 'use strict'; /** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ From 72a4b22122268dfbb3142b8af2ea7ad77b6995b7 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Wed, 23 Sep 2020 12:42:05 -0700 Subject: [PATCH 10/23] Update devtools test --- .../devtools/lighthouse/lighthouse-export-run-expected.txt | 6 +++--- .../lighthouse/lighthouse-successful-run-expected.txt | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt index 57304d5d24dc..c03cb6ed3825 100644 --- a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt +++ b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt @@ -2,11 +2,11 @@ Tests that exporting works. ++++++++ testExportHtml -# of .lh-audit divs (original): 136 +# of .lh-audit divs (original): 137 -# of .lh-audit divs (exported html): 136 +# of .lh-audit divs (exported html): 137 ++++++++ testExportJson -# of audits (json): 152 +# of audits (json): 153 diff --git a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt index f80c6a402c7b..56c538b96fe0 100644 --- a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt +++ b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-successful-run-expected.txt @@ -330,6 +330,7 @@ Auditing: Properly defines charset Auditing: Avoids an excessive DOM size Auditing: Links to cross-origin destinations are safe Auditing: Avoids requesting the geolocation permission on page load +Auditing: No issues in the `Issues` panel in Chrome Devtools Auditing: Avoids `document.write()` Auditing: Avoids front-end JavaScript libraries with known security vulnerabilities Auditing: Detected JavaScript libraries @@ -458,6 +459,7 @@ form-field-multiple-labels: notApplicable frame-title: notApplicable geolocation-on-start: pass gpt-bids-parallel: notApplicable +has-inspector-issues: pass heading-order: notApplicable hreflang: pass html-has-lang: fail @@ -566,5 +568,5 @@ visual-order-follows-dom: manual without-javascript: pass works-offline: fail -# of .lh-audit divs: 156 +# of .lh-audit divs: 157 From a389e04c22aa4f0e8ba188a14e00812032b84d18 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Fri, 2 Oct 2020 16:27:28 -0700 Subject: [PATCH 11/23] i18n changes Co-authored-by: Brendan Kenny --- .../audits/dobetterweb/has-inspector-issues.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 34470cbdd0b8..75944a392730 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -12,7 +12,7 @@ 'use strict'; -/** @typedef {{issueType: string, description: string, requestUrl?: string}} IssueItem */ +/** @typedef {{issueType: string, description: LH.IcuMessage, requestUrl?: string}} IssueItem */ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); @@ -64,19 +64,19 @@ const UIStrings = { const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); -/** @type {Record} */ +/** @type {Record} */ const heavyAdsMsgMap = { 'NetworkTotalLimit': str_(UIStrings.heavyAdsNetworkLimitMessage), 'CpuTotalLimit': str_(UIStrings.heavyAdsCPUTotalLimitMessage), 'CpuPeakLimit': str_(UIStrings.heavyAdsCPUPeakLimitMessage), }; -/** @type {Object} */ +/** @type {Record} */ const contentSecurityPolicyMsgMap = { 'kInlineViolation': str_(UIStrings.cspInlineViolationMessage), 'kEvalViolation': str_(UIStrings.cspEvalViolationMessage), 'kURLViolation': str_(UIStrings.cspUrlViolationMessage), }; -/** @type {Object} */ +/** @type {Record} */ const blockedByResponseMsgMap = { 'CoepFrameResourceNeedsCoepHeader': str_(UIStrings.coepResourceBlockedMessage), 'CoopSandboxedIFrameCannotNavigateToCoopPage': str_(UIStrings.coopIframeBlockedMessage), From 84b2fcd509d166b722ffe2fbd2a2ae0e852523bb Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Mon, 5 Oct 2020 12:30:17 -0700 Subject: [PATCH 12/23] Improvements --- .../dobetterweb/has-inspector-issues.js | 53 ++---------- .../has-inspector-issues-test.js.snap | 86 +++++++++++++++---- .../dobetterweb/has-inspector-issues-test.js | 6 +- 3 files changed, 79 insertions(+), 66 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 75944a392730..de56fa787b3e 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -104,16 +104,12 @@ class IssuesPanelEntries extends Audit { * @return {Array} */ static getMixedContentItems(mixedContentIssues) { - if (!mixedContentIssues) { - return []; - } - return mixedContentIssues.map(issue => { const requestUrl = issue.request && issue.request.url; return { issueType: 'MixedContent', description: str_(UIStrings.mixedContentMessage), - requestUrl: issue.mainResourceURL || requestUrl, + requestUrl: requestUrl || issue.mainResourceURL, }; }); } @@ -123,16 +119,12 @@ class IssuesPanelEntries extends Audit { * @return {Array} */ static getSameSiteCookieItems(sameSiteCookieIssues) { - if (!sameSiteCookieIssues) { - return []; - } - return sameSiteCookieIssues.map(issue => { const requestUrl = issue.request && issue.request.url; return { issueType: 'SameSiteCookie', description: str_(UIStrings.sameSiteMessage), - requestUrl: issue.cookieUrl || requestUrl, + requestUrl: requestUrl || issue.cookieUrl, }; }); } @@ -142,10 +134,6 @@ class IssuesPanelEntries extends Audit { * @return {Array} */ static getBlockedByResponseItems(blockedByResponseIssues) { - if (!blockedByResponseIssues) { - return []; - } - return blockedByResponseIssues.map(issue => { const blockedReason = issue.reason; return { @@ -161,10 +149,6 @@ class IssuesPanelEntries extends Audit { * @return {Array} */ static getHeavyAdsItems(heavyAdsIssues) { - if (!heavyAdsIssues) { - return []; - } - return heavyAdsIssues.map(issue => { const reason = issue.reason; return { @@ -179,10 +163,6 @@ class IssuesPanelEntries extends Audit { * @return {Array} */ static getContentSecurityPolicyItems(cspIssues) { - if (!cspIssues) { - return []; - } - return cspIssues .filter(issue => { // kTrustedTypesSinkViolation and kTrustedTypesPolicyViolation aren't currently supported by the Issues panel @@ -212,28 +192,13 @@ class IssuesPanelEntries extends Audit { ]; const issues = artifacts.InspectorIssues; - /** @type {Array} */ - const items = []; - - for (const [issueType, issuesOfType] of Object.entries(issues)) { - switch (issueType) { - case 'sameSiteCookies': - items.push(...this.getSameSiteCookieItems(issuesOfType)); - break; - case 'mixedContent': - items.push(...this.getMixedContentItems(issuesOfType)); - break; - case 'blockedByResponse': - items.push(...this.getBlockedByResponseItems(issuesOfType)); - break; - case 'heavyAds': - items.push(...this.getHeavyAdsItems(issuesOfType)); - break; - case 'contentSecurityPolicy': - items.push(...this.getContentSecurityPolicyItems(issuesOfType)); - break; - } - } + const items = [ + ...this.getSameSiteCookieItems(issues.sameSiteCookies), + ...this.getMixedContentItems(issues.mixedContent), + ...this.getBlockedByResponseItems(issues.blockedByResponse), + ...this.getHeavyAdsItems(issues.heavyAds), + ...this.getContentSecurityPolicyItems(issues.contentSecurityPolicy), + ]; return { score: items.length > 0 ? 0 : 1, diff --git a/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap b/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap index b54a221511f2..26537ebf6759 100644 --- a/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap +++ b/lighthouse-core/test/audits/dobetterweb/__snapshots__/has-inspector-issues-test.js.snap @@ -3,64 +3,116 @@ exports[`Has inspector issues audit lists the correct description with the associated issue type 1`] = ` Array [ Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage # 0", - "issueType": "MixedContent", - "requestUrl": "www.mixedcontent.com", - }, - Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage # 0", + "description": Object { + "formattedDefault": "A cookie's [\`SameSite\`] attribute was not set or is invalid", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage", + "values": undefined, + }, "issueType": "SameSiteCookie", "requestUrl": "www.samesitecookies.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "description": Object { + "formattedDefault": "Some resources like images, stylesheets or scripts are being accessed over an insecure \`HTTP\` connection", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage", + "values": undefined, + }, + "issueType": "MixedContent", + "requestUrl": "www.mixedcontent.com", + }, + Object { + "description": Object { + "formattedDefault": "A resource was blocked due to not being allowed by a \`Cross-Origin Embedder Policy\`", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage", + "values": undefined, + }, "issueType": "BlockedByResponse", "requestUrl": "www.blockedbyresponse.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage # 0", + "description": Object { + "formattedDefault": "An iframe navigation to a document with a \`Cross-Origin Opener Policy\` was blocked", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage", + "values": undefined, + }, "issueType": "BlockedByResponse", "requestUrl": "www.blockedbyresponse.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage # 0", + "description": Object { + "formattedDefault": "A frame was blocked due to not being allowed by a \`Cross-Origin Embedder Policy\`", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage", + "values": undefined, + }, "issueType": "BlockedByResponse", "requestUrl": "www.blockedbyresponse.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "description": Object { + "formattedDefault": "A resource was blocked due to not being allowed by a \`Cross-Origin Embedder Policy\`", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage", + "values": undefined, + }, "issueType": "BlockedByResponse", "requestUrl": "www.blockedbyresponse.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage # 0", + "description": Object { + "formattedDefault": "A resource was blocked due to not being allowed by a \`Cross-Origin Embedder Policy\`", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage", + "values": undefined, + }, "issueType": "BlockedByResponse", "requestUrl": "www.blockedbyresponse.com", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage # 0", + "description": Object { + "formattedDefault": "The page contains ads that use more than 4 megabytes of network bandwidth", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage", + "values": undefined, + }, "issueType": "HeavyAds", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage # 0", + "description": Object { + "formattedDefault": "The page contains ads that use the main thread for more than 60 seconds in total", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage", + "values": undefined, + }, "issueType": "HeavyAds", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage # 0", + "description": Object { + "formattedDefault": "The page contains ads that use the main thread for more than 15 seconds in a 30 second window", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage", + "values": undefined, + }, "issueType": "HeavyAds", }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage # 0", + "description": Object { + "formattedDefault": "The \`Content Security Policy\` of the page blocks inline execution of scripts and stylesheets", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage", + "values": undefined, + }, "issueType": "ContentSecurityPolicy", "requestUrl": undefined, }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage # 0", + "description": Object { + "formattedDefault": "The \`Content Security Policy\` of the site blocks the use of \`eval\` in JavaScript", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage", + "values": undefined, + }, "issueType": "ContentSecurityPolicy", "requestUrl": undefined, }, Object { - "description": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage # 0", + "description": Object { + "formattedDefault": "The \`Content Security Policy\` of the page blocks some resources because their origin is not included in the content security policy header", + "i18nId": "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage", + "values": undefined, + }, "issueType": "ContentSecurityPolicy", "requestUrl": undefined, }, diff --git a/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js b/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js index 9d5297cd70ff..e623f0b2f518 100644 --- a/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js +++ b/lighthouse-core/test/audits/dobetterweb/has-inspector-issues-test.js @@ -12,16 +12,12 @@ const InspectorIssuesAudit = describe('Has inspector issues audit', () => { it('passes when no issues are found', () => { + /** @type {LH.Artifacts.InspectorIssues} */ const issues = { - /** @type {Array} */ mixedContent: [], - /** @type {Array} */ sameSiteCookies: [], - /** @type {Array} */ blockedByResponse: [], - /** @type {Array} */ heavyAds: [], - /** @type {Array} */ contentSecurityPolicy: [], }; const auditResult = InspectorIssuesAudit.audit({ From 0446e774fa925cc798c375c51116d1fc933b3b24 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Mon, 5 Oct 2020 12:53:27 -0700 Subject: [PATCH 13/23] Update devtools test --- .../devtools/lighthouse/lighthouse-export-run-expected.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt index c03cb6ed3825..57304d5d24dc 100644 --- a/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt +++ b/third-party/chromium-webtests/webtests/http/tests/devtools/lighthouse/lighthouse-export-run-expected.txt @@ -2,11 +2,11 @@ Tests that exporting works. ++++++++ testExportHtml -# of .lh-audit divs (original): 137 +# of .lh-audit divs (original): 136 -# of .lh-audit divs (exported html): 137 +# of .lh-audit divs (exported html): 136 ++++++++ testExportJson -# of audits (json): 153 +# of audits (json): 152 From 52815d1b1f112f8647003d01adef71500ef3a4db Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Wed, 7 Oct 2020 12:12:11 -0700 Subject: [PATCH 14/23] Axed the descriptions --- .../dobetterweb/has-inspector-issues.js | 207 ++++++++++-------- .../gather/gatherers/inspector-issues.js | 36 ++- 2 files changed, 131 insertions(+), 112 deletions(-) diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index de56fa787b3e..1f58e5646951 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -12,54 +12,45 @@ 'use strict'; -/** @typedef {{issueType: string, description: LH.IcuMessage, requestUrl?: string}} IssueItem */ +/** @typedef {{url: string}} IssueSubItem */ +/** @typedef {{issueType: string|LH.IcuMessage, subItems: Array}} IssueItem */ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { + /* eslint-disable max-len */ /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when no issues were logged into the Chrome DevTools Issues panel. */ title: 'No issues in the `Issues` panel in Chrome Devtools', /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when issues are detected and logged into the Chrome DevTools Issues panel. */ failureTitle: 'Issues were logged in the `Issues` panel in Chrome Devtools', /** Description of a Lighthouse audit that tells the user why issues being logged to the Chrome DevTools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ - description: 'Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. ' + - 'They can come from network request failures, insufficient security controls, ' + - ' and other browser concerns. ', + description: 'Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns.', /** Table column header for the type of issue. */ - columnIssueType: 'Issue', + columnIssueType: 'Issue Type', /** Message shown in a data table when the item is a SameSiteCookie issue. */ sameSiteMessage: 'A cookie\'s [`SameSite`] attribute was not set or is invalid', /** Message shown in a data table when the item is a MixedContent issue. This is when some resources are loaded over an insecure HTTP connection. */ - mixedContentMessage: 'Some resources like images, stylesheets or scripts ' + - 'are being accessed over an insecure `HTTP` connection', + mixedContentMessage: 'Some resources like images, stylesheets or scripts are being accessed over an insecure `HTTP` connection', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a resource is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ - coepResourceBlockedMessage: 'A resource was blocked due to not being ' + - 'allowed by a `Cross-Origin Embedder Policy`', + coepResourceBlockedMessage: 'A resource was blocked due to not being allowed by a `Cross-Origin Embedder Policy`', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a frame is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ - coepFrameBlockedMessage: 'A frame was blocked due to not being ' + - 'allowed by a `Cross-Origin Embedder Policy`', + coepFrameBlockedMessage: 'A frame was blocked due to not being allowed by a `Cross-Origin Embedder Policy`', /** Message shown in a data table when the item is a BlockedByResponse issue. This is when navigation to a document with a Cross-Origin Opener Policy is blocked. */ - coopIframeBlockedMessage: 'An iframe navigation to a document with ' + - 'a `Cross-Origin Opener Policy` was blocked', + coopIframeBlockedMessage: 'An iframe navigation to a document with a `Cross-Origin Opener Policy` was blocked', /** Message shown in a data table when the item is a HeavyAds issue where an ad uses more than 4 megabytes of network bandwith. */ - heavyAdsNetworkLimitMessage: 'The page contains ads that use ' + - 'more than 4 megabytes of network bandwidth', + heavyAdsNetworkLimitMessage: 'The page contains ads that use more than 4 megabytes of network bandwidth', /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 60 seconds in total. */ - heavyAdsCPUTotalLimitMessage: 'The page contains ads that use the ' + - 'main thread for more than 60 seconds in total', + heavyAdsCPUTotalLimitMessage: 'The page contains ads that use the main thread for more than 60 seconds in total', /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 15 seconds in any 30 second window. */ - heavyAdsCPUPeakLimitMessage: 'The page contains ads that use the ' + - 'main thread for more than 15 seconds in a 30 second window', + heavyAdsCPUPeakLimitMessage: 'The page contains ads that use the main thread for more than 15 seconds in a 30 second window', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where resources are blocked due to not being in the Content Security Policy header. */ - cspUrlViolationMessage: 'The `Content Security Policy` of the page blocks some resources because ' + - 'their origin is not included in the content security policy header', + cspUrlViolationMessage: 'The `Content Security Policy` of the page blocks some resources because their origin is not included in the content security policy header', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks inline execution of scripts and stylesheets. */ - cspInlineViolationMessage: 'The `Content Security Policy` of the page blocks ' + - 'inline execution of scripts and stylesheets', + cspInlineViolationMessage: 'The `Content Security Policy` of the page blocks inline execution of scripts and stylesheets', /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks the use of the `eval` function in Javascript. */ - cspEvalViolationMessage: 'The `Content Security Policy` of the site blocks ' + - 'the use of `eval` in JavaScript', + cspEvalViolationMessage: 'The `Content Security Policy` of the site blocks the use of `eval` in JavaScript', + /* eslint-enable max-len */ }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); @@ -100,83 +91,113 @@ class IssuesPanelEntries extends Audit { } /** - * @param {Array} mixedContentIssues - * @return {Array} + * @param {Array { - const requestUrl = issue.request && issue.request.url; - return { - issueType: 'MixedContent', - description: str_(UIStrings.mixedContentMessage), - requestUrl: requestUrl || issue.mainResourceURL, - }; - }); + static getMixedContentRow(mixedContentIssues) { + const requestUrls = new Set(); + for (const issue of mixedContentIssues) { + const requestUrl = (issue.request && issue.request.url) || issue.mainResourceURL; + if (requestUrl) { + requestUrls.add(requestUrl); + } + } + return { + issueType: 'Mixed Content', + subItems: { + type: 'subitems', + items: Array.from(requestUrls).map(url => { + return { + url, + }; + }), + }, + }; } /** * @param {Array} sameSiteCookieIssues - * @return {Array} + * @return {LH.Audit.Details.TableItem} */ - static getSameSiteCookieItems(sameSiteCookieIssues) { - return sameSiteCookieIssues.map(issue => { - const requestUrl = issue.request && issue.request.url; - return { - issueType: 'SameSiteCookie', - description: str_(UIStrings.sameSiteMessage), - requestUrl: requestUrl || issue.cookieUrl, - }; - }); + static getSameSiteCookieRow(sameSiteCookieIssues) { + const requestUrls = new Set(); + for (const issue of sameSiteCookieIssues) { + const requestUrl = (issue.request && issue.request.url) || issue.cookieUrl; + if (requestUrl) { + requestUrls.add(requestUrl); + } + } + return { + issueType: 'SameSite Cookie', + subItems: { + type: 'subitems', + items: Array.from(requestUrls).map(url => { + return { + url, + }; + }), + }, + }; } /** * @param {Array} blockedByResponseIssues - * @return {Array} + * @return {LH.Audit.Details.TableItem} */ - static getBlockedByResponseItems(blockedByResponseIssues) { - return blockedByResponseIssues.map(issue => { - const blockedReason = issue.reason; - return { - issueType: 'BlockedByResponse', - description: blockedByResponseMsgMap[blockedReason], - requestUrl: issue.request.url, - }; - }); + static getBlockedByResponseRow(blockedByResponseIssues) { + const requestUrls = new Set(); + for (const issue of blockedByResponseIssues) { + const requestUrl = issue.request && issue.request.url; + if (requestUrl) { + requestUrls.add(requestUrl); + } + } + return { + issueType: 'Blocked By Response', + subItems: { + type: 'subitems', + items: Array.from(requestUrls).map(url => { + return { + url, + }; + }), + }, + }; } /** * @param {Array} heavyAdsIssues - * @return {Array} + * @return {LH.Audit.Details.TableItem} */ - static getHeavyAdsItems(heavyAdsIssues) { - return heavyAdsIssues.map(issue => { - const reason = issue.reason; - return { - issueType: 'HeavyAds', - description: heavyAdsMsgMap[reason], - }; - }); + static getHeavyAdsRow(heavyAdsIssues) { + return { + issueType: 'Heavy Ads', + }; } /** * @param {Array} cspIssues - * @return {Array} + * @return {LH.Audit.Details.TableItem} */ - static getContentSecurityPolicyItems(cspIssues) { - return cspIssues - .filter(issue => { - // kTrustedTypesSinkViolation and kTrustedTypesPolicyViolation aren't currently supported by the Issues panel - return issue.contentSecurityPolicyViolationType !== 'kTrustedTypesSinkViolation' && - issue.contentSecurityPolicyViolationType !== 'kTrustedTypesPolicyViolation'; - }) - .map(issue => { - const blockedUrl = issue.blockedURL; - return { - issueType: 'ContentSecurityPolicy', - description: contentSecurityPolicyMsgMap[issue.contentSecurityPolicyViolationType], - requestUrl: blockedUrl, - }; - }); + static getContentSecurityPolicyRow(cspIssues) { + const requestUrls = new Set(); + for (const issue of cspIssues) { + const requestUrl = issue.blockedURL; + if (requestUrl) { + requestUrls.add(requestUrl); + } + } + return { + issueType: 'Blocked By Response', + subItems: { + type: 'subitems', + items: Array.from(requestUrls).map(url => { + return { + url, + }; + }), + }, + }; } /** @@ -186,19 +207,23 @@ class IssuesPanelEntries extends Audit { static audit(artifacts) { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ - {key: 'issueType', itemType: 'text', text: str_(UIStrings.columnIssueType)}, - {key: 'description', itemType: 'text', text: str_(i18n.UIStrings.columnDescription)}, - {key: 'requestUrl', itemType: 'url', text: 'Request URL'}, + {key: 'issueType', itemType: 'text', subItemsHeading: {key: 'url', itemType: 'url'}, text: str_(UIStrings.columnIssueType)}, ]; const issues = artifacts.InspectorIssues; - const items = [ - ...this.getSameSiteCookieItems(issues.sameSiteCookies), - ...this.getMixedContentItems(issues.mixedContent), - ...this.getBlockedByResponseItems(issues.blockedByResponse), - ...this.getHeavyAdsItems(issues.heavyAds), - ...this.getContentSecurityPolicyItems(issues.contentSecurityPolicy), - ]; + /** @type LH.Audit.Details.TableItem[] */ + const items = []; + + if (issues.mixedContent.length) items.push(this.getMixedContentRow(issues.mixedContent)); + if (issues.sameSiteCookies.length) items.push(this.getSameSiteCookieRow(issues.sameSiteCookies)); + if (issues.blockedByResponse.length) items.push(this.getBlockedByResponseRow(issues.blockedByResponse)); + if (issues.heavyAds.length) items.push(this.getHeavyAdsRow(issues.heavyAds)); + const cspIssues = issues.contentSecurityPolicy.filter(issue => { + // kTrustedTypesSinkViolation and kTrustedTypesPolicyViolation aren't currently supported by the Issues panel + return issue.contentSecurityPolicyViolationType !== 'kTrustedTypesSinkViolation' && + issue.contentSecurityPolicyViolationType !== 'kTrustedTypesPolicyViolation'; + }); + if (cspIssues.length) items.push(this.getContentSecurityPolicyRow(cspIssues)); return { score: items.length > 0 ? 0 : 1, diff --git a/lighthouse-core/gather/gatherers/inspector-issues.js b/lighthouse-core/gather/gatherers/inspector-issues.js index b28a9203bf57..4a57d34a55df 100644 --- a/lighthouse-core/gather/gatherers/inspector-issues.js +++ b/lighthouse-core/gather/gatherers/inspector-issues.js @@ -59,27 +59,21 @@ class InspectorIssues extends Gatherer { }; for (const issue of this._issues) { - switch (issue.code) { - case 'MixedContentIssue': - issue.details.mixedContentIssueDetails && - artifact.mixedContent.push(issue.details.mixedContentIssueDetails); - break; - case 'SameSiteCookieIssue': - issue.details.sameSiteCookieIssueDetails && - artifact.sameSiteCookies.push(issue.details.sameSiteCookieIssueDetails); - break; - case 'BlockedByResponseIssue': - issue.details.blockedByResponseIssueDetails && - artifact.blockedByResponse.push(issue.details.blockedByResponseIssueDetails); - break; - case 'HeavyAdIssue': - issue.details.heavyAdIssueDetails && - artifact.heavyAds.push(issue.details.heavyAdIssueDetails); - break; - case 'ContentSecurityPolicyIssue': - issue.details.contentSecurityPolicyIssueDetails && - artifact.contentSecurityPolicy.push(issue.details.contentSecurityPolicyIssueDetails); - } + if (issue.details.mixedContentIssueDetails) { + artifact.mixedContent.push(issue.details.mixedContentIssueDetails); + } + if (issue.details.sameSiteCookieIssueDetails) { + artifact.sameSiteCookies.push(issue.details.sameSiteCookieIssueDetails); + } + if (issue.details.blockedByResponseIssueDetails) { + artifact.blockedByResponse.push(issue.details.blockedByResponseIssueDetails); + } + if (issue.details.heavyAdIssueDetails) { + artifact.heavyAds.push(issue.details.heavyAdIssueDetails); + } + if (issue.details.contentSecurityPolicyIssueDetails) { + artifact.contentSecurityPolicy.push(issue.details.contentSecurityPolicyIssueDetails); + } } return artifact; From b6789d890eb4fb12dc0b37037586ce7dec7bc343 Mon Sep 17 00:00:00 2001 From: Michael Blasingame Date: Wed, 7 Oct 2020 16:08:06 -0700 Subject: [PATCH 15/23] Remove description strings --- .../dobetterweb/has-inspector-issues.js | 94 +- .../gather/gatherers/inspector-issues.js | 30 +- lighthouse-core/lib/i18n/locales/en-US.json | 39 +- lighthouse-core/lib/i18n/locales/en-XL.json | 39 +- .../test/results/artifacts/lhr.json | 8147 +++++++++++++++++ lighthouse-core/test/results/sample_v2.json | 14 +- 6 files changed, 8207 insertions(+), 156 deletions(-) create mode 100644 lighthouse-core/test/results/artifacts/lhr.json diff --git a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js index 1f58e5646951..39155d84161d 100644 --- a/lighthouse-core/audits/dobetterweb/has-inspector-issues.js +++ b/lighthouse-core/audits/dobetterweb/has-inspector-issues.js @@ -4,7 +4,7 @@ * 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. */ - /** +/** * @fileoverview Audits a page to determine whether it generates issues in the Issues panel of Chrome Devtools. * The audit is meant to maintain parity with the Chrome Devtools Issues panel front end. * https://source.chromium.org/chromium/chromium/src/+/master:third_party/devtools-frontend/src/front_end/sdk/ @@ -19,63 +19,24 @@ const Audit = require('../audit.js'); const i18n = require('../../lib/i18n/i18n.js'); const UIStrings = { - /* eslint-disable max-len */ /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when no issues were logged into the Chrome DevTools Issues panel. */ title: 'No issues in the `Issues` panel in Chrome Devtools', /** Title of a Lighthouse audit that provides detail on various types of issues with the page. This descriptive title is shown to users when issues are detected and logged into the Chrome DevTools Issues panel. */ failureTitle: 'Issues were logged in the `Issues` panel in Chrome Devtools', + /* eslint-disable max-len */ /** Description of a Lighthouse audit that tells the user why issues being logged to the Chrome DevTools Issues panel are a cause for concern and so should be fixed. This is displayed after a user expands the section to see more. No character length limits. */ - description: 'Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns.', + description: 'Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. Open up the Issues panel in Chrome DevTools for more details on each issue.', + /* eslint-enable max-len */ /** Table column header for the type of issue. */ columnIssueType: 'Issue Type', - /** Message shown in a data table when the item is a SameSiteCookie issue. */ - sameSiteMessage: 'A cookie\'s [`SameSite`] attribute was not set or is invalid', - /** Message shown in a data table when the item is a MixedContent issue. This is when some resources are loaded over an insecure HTTP connection. */ - mixedContentMessage: 'Some resources like images, stylesheets or scripts are being accessed over an insecure `HTTP` connection', - /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a resource is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ - coepResourceBlockedMessage: 'A resource was blocked due to not being allowed by a `Cross-Origin Embedder Policy`', - /** Message shown in a data table when the item is a BlockedByResponse issue. This is when a frame is blocked due to not being allowed by a Cross-Origin Embedder Policy. */ - coepFrameBlockedMessage: 'A frame was blocked due to not being allowed by a `Cross-Origin Embedder Policy`', - /** Message shown in a data table when the item is a BlockedByResponse issue. This is when navigation to a document with a Cross-Origin Opener Policy is blocked. */ - coopIframeBlockedMessage: 'An iframe navigation to a document with a `Cross-Origin Opener Policy` was blocked', - /** Message shown in a data table when the item is a HeavyAds issue where an ad uses more than 4 megabytes of network bandwith. */ - heavyAdsNetworkLimitMessage: 'The page contains ads that use more than 4 megabytes of network bandwidth', - /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 60 seconds in total. */ - heavyAdsCPUTotalLimitMessage: 'The page contains ads that use the main thread for more than 60 seconds in total', - /** Message shown in a data table when the item is a HeavyAds issue where an ad has used the main thread for more than 15 seconds in any 30 second window. */ - heavyAdsCPUPeakLimitMessage: 'The page contains ads that use the main thread for more than 15 seconds in a 30 second window', - /** Message shown in a data table when the item is a ContentSecurityPolicy issue where resources are blocked due to not being in the Content Security Policy header. */ - cspUrlViolationMessage: 'The `Content Security Policy` of the page blocks some resources because their origin is not included in the content security policy header', - /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks inline execution of scripts and stylesheets. */ - cspInlineViolationMessage: 'The `Content Security Policy` of the page blocks inline execution of scripts and stylesheets', - /** Message shown in a data table when the item is a ContentSecurityPolicy issue where the Content Security Policy blocks the use of the `eval` function in Javascript. */ - cspEvalViolationMessage: 'The `Content Security Policy` of the site blocks the use of `eval` in JavaScript', - /* eslint-enable max-len */ + /** The type of an Issue in Chrome DevTools when a resource is blocked due to receiving a rejection in the response to a request made on the page. */ + issueTypeBlockedByResponse: 'Blocked By Response', + /** The type of an Issue in Chrome DevTools when a site has large ads that use up a lot of the browser's resources. */ + issueTypeHeavyAds: 'Heavy Ads', }; const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); -/** @type {Record} */ -const heavyAdsMsgMap = { - 'NetworkTotalLimit': str_(UIStrings.heavyAdsNetworkLimitMessage), - 'CpuTotalLimit': str_(UIStrings.heavyAdsCPUTotalLimitMessage), - 'CpuPeakLimit': str_(UIStrings.heavyAdsCPUPeakLimitMessage), -}; -/** @type {Record} */ -const contentSecurityPolicyMsgMap = { - 'kInlineViolation': str_(UIStrings.cspInlineViolationMessage), - 'kEvalViolation': str_(UIStrings.cspEvalViolationMessage), - 'kURLViolation': str_(UIStrings.cspUrlViolationMessage), -}; -/** @type {Record} */ -const blockedByResponseMsgMap = { - 'CoepFrameResourceNeedsCoepHeader': str_(UIStrings.coepResourceBlockedMessage), - 'CoopSandboxedIFrameCannotNavigateToCoopPage': str_(UIStrings.coopIframeBlockedMessage), - 'CorpNotSameOrigin': str_(UIStrings.coepResourceBlockedMessage), - 'CorpNotSameOriginAfterDefaultedToSameOriginByCoep': str_(UIStrings.coepFrameBlockedMessage), - 'CorpNotSameSite': str_(UIStrings.coepResourceBlockedMessage), -}; - class IssuesPanelEntries extends Audit { /** * @return {LH.Audit.Meta} @@ -153,7 +114,7 @@ class IssuesPanelEntries extends Audit { } } return { - issueType: 'Blocked By Response', + issueType: str_(UIStrings.issueTypeBlockedByResponse), subItems: { type: 'subitems', items: Array.from(requestUrls).map(url => { @@ -165,21 +126,11 @@ class IssuesPanelEntries extends Audit { }; } - /** - * @param {Array} heavyAdsIssues - * @return {LH.Audit.Details.TableItem} - */ - static getHeavyAdsRow(heavyAdsIssues) { - return { - issueType: 'Heavy Ads', - }; - } - /** * @param {Array} cspIssues * @return {LH.Audit.Details.TableItem} */ - static getContentSecurityPolicyRow(cspIssues) { + static getContentSecurityPolicyRow(cspIssues) { const requestUrls = new Set(); for (const issue of cspIssues) { const requestUrl = issue.blockedURL; @@ -197,7 +148,7 @@ class IssuesPanelEntries extends Audit { }; }), }, - }; + }; } /** @@ -207,24 +158,35 @@ class IssuesPanelEntries extends Audit { static audit(artifacts) { /** @type {LH.Audit.Details.Table['headings']} */ const headings = [ + /* eslint-disable max-len */ {key: 'issueType', itemType: 'text', subItemsHeading: {key: 'url', itemType: 'url'}, text: str_(UIStrings.columnIssueType)}, + /* eslint-enable max-len */ ]; const issues = artifacts.InspectorIssues; /** @type LH.Audit.Details.TableItem[] */ const items = []; - if (issues.mixedContent.length) items.push(this.getMixedContentRow(issues.mixedContent)); - if (issues.sameSiteCookies.length) items.push(this.getSameSiteCookieRow(issues.sameSiteCookies)); - if (issues.blockedByResponse.length) items.push(this.getBlockedByResponseRow(issues.blockedByResponse)); - if (issues.heavyAds.length) items.push(this.getHeavyAdsRow(issues.heavyAds)); + if (issues.mixedContent.length) { + items.push(this.getMixedContentRow(issues.mixedContent)); + } + if (issues.sameSiteCookies.length) { + items.push(this.getSameSiteCookieRow(issues.sameSiteCookies)); + } + if (issues.blockedByResponse.length) { + items.push(this.getBlockedByResponseRow(issues.blockedByResponse)); + } + if (issues.heavyAds.length) { + items.push({issueType: str_(UIStrings.issueTypeHeavyAds)}); + } const cspIssues = issues.contentSecurityPolicy.filter(issue => { // kTrustedTypesSinkViolation and kTrustedTypesPolicyViolation aren't currently supported by the Issues panel return issue.contentSecurityPolicyViolationType !== 'kTrustedTypesSinkViolation' && issue.contentSecurityPolicyViolationType !== 'kTrustedTypesPolicyViolation'; }); - if (cspIssues.length) items.push(this.getContentSecurityPolicyRow(cspIssues)); - + if (cspIssues.length) { + items.push(this.getContentSecurityPolicyRow(cspIssues)); + } return { score: items.length > 0 ? 0 : 1, details: Audit.makeTableDetails(headings, items), diff --git a/lighthouse-core/gather/gatherers/inspector-issues.js b/lighthouse-core/gather/gatherers/inspector-issues.js index 4a57d34a55df..97efafd64bb7 100644 --- a/lighthouse-core/gather/gatherers/inspector-issues.js +++ b/lighthouse-core/gather/gatherers/inspector-issues.js @@ -59,21 +59,21 @@ class InspectorIssues extends Gatherer { }; for (const issue of this._issues) { - if (issue.details.mixedContentIssueDetails) { - artifact.mixedContent.push(issue.details.mixedContentIssueDetails); - } - if (issue.details.sameSiteCookieIssueDetails) { - artifact.sameSiteCookies.push(issue.details.sameSiteCookieIssueDetails); - } - if (issue.details.blockedByResponseIssueDetails) { - artifact.blockedByResponse.push(issue.details.blockedByResponseIssueDetails); - } - if (issue.details.heavyAdIssueDetails) { - artifact.heavyAds.push(issue.details.heavyAdIssueDetails); - } - if (issue.details.contentSecurityPolicyIssueDetails) { - artifact.contentSecurityPolicy.push(issue.details.contentSecurityPolicyIssueDetails); - } + if (issue.details.mixedContentIssueDetails) { + artifact.mixedContent.push(issue.details.mixedContentIssueDetails); + } + if (issue.details.sameSiteCookieIssueDetails) { + artifact.sameSiteCookies.push(issue.details.sameSiteCookieIssueDetails); + } + if (issue.details.blockedByResponseIssueDetails) { + artifact.blockedByResponse.push(issue.details.blockedByResponseIssueDetails); + } + if (issue.details.heavyAdIssueDetails) { + artifact.heavyAds.push(issue.details.heavyAdIssueDetails); + } + if (issue.details.contentSecurityPolicyIssueDetails) { + artifact.contentSecurityPolicy.push(issue.details.contentSecurityPolicyIssueDetails); + } } return artifact; diff --git a/lighthouse-core/lib/i18n/locales/en-US.json b/lighthouse-core/lib/i18n/locales/en-US.json index 7ab423c3ffd2..16563f5c567e 100644 --- a/lighthouse-core/lib/i18n/locales/en-US.json +++ b/lighthouse-core/lib/i18n/locales/en-US.json @@ -665,47 +665,20 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Avoids requesting the geolocation permission on page load" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage": { - "message": "A frame was blocked due to not being allowed by a `Cross-Origin Embedder Policy`" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage": { - "message": "A resource was blocked due to not being allowed by a `Cross-Origin Embedder Policy`" - }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | columnIssueType": { - "message": "Issue" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage": { - "message": "An iframe navigation to a document with a `Cross-Origin Opener Policy` was blocked" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage": { - "message": "The `Content Security Policy` of the site blocks the use of `eval` in JavaScript" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage": { - "message": "The `Content Security Policy` of the page blocks inline execution of scripts and stylesheets" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage": { - "message": "The `Content Security Policy` of the page blocks some resources because their origin is not included in the content security policy header" + "message": "Issue Type" }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | description": { - "message": "Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. " + "message": "Issues logged to the `Issues` panel in Chrome Devtools indicate unresolved problems. They can come from network request failures, insufficient security controls, and other browser concerns. Open up the Issues panel in Chrome DevTools for more details on each issue." }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | failureTitle": { "message": "Issues were logged in the `Issues` panel in Chrome Devtools" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage": { - "message": "The page contains ads that use the main thread for more than 15 seconds in a 30 second window" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage": { - "message": "The page contains ads that use the main thread for more than 60 seconds in total" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage": { - "message": "The page contains ads that use more than 4 megabytes of network bandwidth" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage": { - "message": "Some resources like images, stylesheets or scripts are being accessed over an insecure `HTTP` connection" + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | issueTypeBlockedByResponse": { + "message": "Blocked By Response" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage": { - "message": "A cookie's [`SameSite`] attribute was not set or is invalid" + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | issueTypeHeavyAds": { + "message": "Heavy Ads" }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | title": { "message": "No issues in the `Issues` panel in Chrome Devtools" diff --git a/lighthouse-core/lib/i18n/locales/en-XL.json b/lighthouse-core/lib/i18n/locales/en-XL.json index 3dabe65148a2..34a572e73d68 100644 --- a/lighthouse-core/lib/i18n/locales/en-XL.json +++ b/lighthouse-core/lib/i18n/locales/en-XL.json @@ -665,47 +665,20 @@ "lighthouse-core/audits/dobetterweb/geolocation-on-start.js | title": { "message": "Âv́ôíd̂ś r̂éq̂úêśt̂ín̂ǵ t̂h́ê ǵêól̂óĉát̂íôń p̂ér̂ḿîśŝíôń ôń p̂áĝé l̂óâd́" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepFrameBlockedMessage": { - "message": " f́r̂ám̂é ŵáŝ b́l̂óĉḱêd́ d̂úê t́ô ńôt́ b̂éîńĝ ál̂ĺôẃêd́ b̂ý â `Cross-Origin Embedder Policy`" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coepResourceBlockedMessage": { - "message": " ŕêśôúr̂ćê ẃâś b̂ĺôćk̂éd̂ d́ûé t̂ó n̂ót̂ b́êín̂ǵ âĺl̂óŵéd̂ b́ŷ á `Cross-Origin Embedder Policy`" - }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | columnIssueType": { - "message": "Îśŝúê" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | coopIframeBlockedMessage": { - "message": "Âń îf́r̂ám̂é n̂áv̂íĝát̂íôń t̂ó â d́ôćûḿêńt̂ ẃît́ĥ á `Cross-Origin Opener Policy` ŵáŝ b́l̂óĉḱêd́" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspEvalViolationMessage": { - "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé ŝít̂é b̂ĺôćk̂ś t̂h́ê úŝé ôf́ `eval` îń Ĵáv̂áŜćr̂íp̂t́" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspInlineViolationMessage": { - "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé p̂áĝé b̂ĺôćk̂ś îńl̂ín̂é êx́êćût́îón̂ óf̂ śĉŕîṕt̂ś âńd̂ śt̂ýl̂éŝh́êét̂ś" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | cspUrlViolationMessage": { - "message": "T̂h́ê `Content Security Policy` óf̂ t́ĥé p̂áĝé b̂ĺôćk̂ś ŝóm̂é r̂éŝóûŕĉéŝ b́êćâúŝé t̂h́êír̂ ór̂íĝín̂ íŝ ńôt́ îńĉĺûd́êd́ îń t̂h́ê ćôńt̂én̂t́ ŝéĉúr̂ít̂ý p̂ól̂íĉý ĥéâd́êŕ" + "message": "Îśŝúê T́ŷṕê" }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | description": { - "message": "Îśŝúêś l̂óĝǵêd́ t̂ó t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś îńd̂íĉát̂é ûńr̂éŝól̂v́êd́ p̂ŕôb́l̂ém̂ś. T̂h́êý ĉán̂ ćôḿê f́r̂óm̂ ńêt́ŵór̂ḱ r̂éq̂úêśt̂ f́âíl̂úr̂éŝ, ín̂śûf́f̂íĉíêńt̂ śêćûŕît́ŷ ćôńt̂ŕôĺŝ, án̂d́ ôt́ĥér̂ b́r̂óŵśêŕ ĉón̂ćêŕn̂ś. " + "message": "Îśŝúêś l̂óĝǵêd́ t̂ó t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś îńd̂íĉát̂é ûńr̂éŝól̂v́êd́ p̂ŕôb́l̂ém̂ś. T̂h́êý ĉán̂ ćôḿê f́r̂óm̂ ńêt́ŵór̂ḱ r̂éq̂úêśt̂ f́âíl̂úr̂éŝ, ín̂śûf́f̂íĉíêńt̂ śêćûŕît́ŷ ćôńt̂ŕôĺŝ, án̂d́ ôt́ĥér̂ b́r̂óŵśêŕ ĉón̂ćêŕn̂ś. Ôṕêń ûṕ t̂h́ê Íŝśûéŝ ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂T́ôól̂ś f̂ór̂ ḿôŕê d́êt́âíl̂ś ôń êáĉh́ îśŝúê." }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | failureTitle": { "message": "Îśŝúêś ŵér̂é l̂óĝǵêd́ îń t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUPeakLimitMessage": { - "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê t́ĥé m̂áîń t̂h́r̂éâd́ f̂ór̂ ḿôŕê t́ĥán̂ 15 śêćôńd̂ś îń â 30 śêćôńd̂ ẃîńd̂óŵ" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsCPUTotalLimitMessage": { - "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê t́ĥé m̂áîń t̂h́r̂éâd́ f̂ór̂ ḿôŕê t́ĥán̂ 60 śêćôńd̂ś îń t̂ót̂ál̂" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | heavyAdsNetworkLimitMessage": { - "message": "T̂h́ê ṕâǵê ćôńt̂áîńŝ ád̂ś t̂h́ât́ ûśê ḿôŕê t́ĥán̂ 4 ḿêǵâb́ŷt́êś ôf́ n̂ét̂ẃôŕk̂ b́âńd̂ẃîd́t̂h́" - }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | mixedContentMessage": { - "message": "Ŝóm̂é r̂éŝóûŕĉéŝ ĺîḱê ím̂áĝéŝ, śt̂ýl̂éŝh́êét̂ś ôŕ ŝćr̂íp̂t́ŝ ár̂é b̂éîńĝ áĉćêśŝéd̂ óv̂ér̂ án̂ ín̂śêćûŕê `HTTP` ćôńn̂éĉt́îón̂" + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | issueTypeBlockedByResponse": { + "message": "B̂ĺôćk̂éd̂ B́ŷ Ŕêśp̂ón̂śê" }, - "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | sameSiteMessage": { - "message": " ćôók̂íê'ś [`SameSite`] ât́t̂ŕîb́ût́ê ẃâś n̂ót̂ śêt́ ôŕ îś îńv̂ál̂íd̂" + "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | issueTypeHeavyAds": { + "message": "Ĥéâv́ŷ Ád̂ś" }, "lighthouse-core/audits/dobetterweb/has-inspector-issues.js | title": { "message": "N̂ó îśŝúêś îń t̂h́ê `Issues` ṕâńêĺ îń Ĉh́r̂óm̂é D̂év̂t́ôól̂ś" diff --git a/lighthouse-core/test/results/artifacts/lhr.json b/lighthouse-core/test/results/artifacts/lhr.json new file mode 100644 index 000000000000..116fd73d7321 --- /dev/null +++ b/lighthouse-core/test/results/artifacts/lhr.json @@ -0,0 +1,8147 @@ +{ + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4232.0 Safari/537.36", + "environment": { + "networkUserAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36(KHTML, like Gecko) Chrome/66.0.3359.30 Mobile Safari/537.36", + "hostUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4232.0 Safari/537.36", + "benchmarkIndex": 1000, + "credits": { + "axe-core": "3.5.5" + } + }, + "lighthouseVersion": "6.4.1", + "fetchTime": "2018-03-13T00:55:45.840Z", + "requestedUrl": "http://localhost:10200/dobetterweb/dbw_tester.html", + "finalUrl": "http://localhost:10200/dobetterweb/dbw_tester.html", + "runWarnings": [], + "audits": { + "is-on-https": { + "id": "is-on-https", + "title": "Does not use HTTPS", + "description": "All sites should be protected with HTTPS, even ones that don't handle sensitive data. This includes avoiding [mixed content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content), where some resources are loaded over HTTP despite the initial request being served over HTTPS. HTTPS prevents intruders from tampering with or passively listening in on the communications between your app and your users, and is a prerequisite for HTTP/2 and many new web platform APIs. [Learn more](https://web.dev/is-on-https/).", + "score": 0, + "scoreDisplayMode": "binary", + "displayValue": "1 insecure request found", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "Insecure URL" + }, + { + "key": "resolution", + "itemType": "text", + "text": "Request Resolution" + } + ], + "items": [ + { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "resolution": "Allowed" + } + ] + } + }, + "redirects-http": { + "id": "redirects-http", + "title": "Does not redirect HTTP traffic to HTTPS", + "description": "If you've already set up HTTPS, make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://web.dev/redirects-http/).", + "score": 0, + "scoreDisplayMode": "binary" + }, + "service-worker": { + "id": "service-worker", + "title": "Does not register a service worker that controls page and `start_url`", + "description": "The service worker is the technology that enables your app to use many Progressive Web App features, such as offline, add to homescreen, and push notifications. [Learn more](https://web.dev/service-worker/).", + "score": 0, + "scoreDisplayMode": "binary" + }, + "works-offline": { + "id": "works-offline", + "title": "Current page does not respond with a 200 when offline", + "description": "If you're building a Progressive Web App, consider using a service worker so that your app can work offline. [Learn more](https://web.dev/works-offline/).", + "score": 0, + "scoreDisplayMode": "binary", + "warnings": [] + }, + "viewport": { + "id": "viewport", + "title": "Has a `` tag with `width` or `initial-scale`", + "description": "Add a `` tag to optimize your app for mobile screens. [Learn more](https://web.dev/viewport/).", + "score": 1, + "scoreDisplayMode": "binary", + "warnings": [] + }, + "without-javascript": { + "id": "without-javascript", + "title": "Contains some content when JavaScript is not available", + "description": "Your app should display some content when JavaScript is disabled, even if it's just a warning to the user that JavaScript is required to use the app. [Learn more](https://web.dev/without-javascript/).", + "score": 1, + "scoreDisplayMode": "binary" + }, + "first-contentful-paint": { + "id": "first-contentful-paint", + "title": "First Contentful Paint", + "description": "First Contentful Paint marks the time at which the first text or image is painted. [Learn more](https://web.dev/first-contentful-paint/).", + "score": 0.51, + "scoreDisplayMode": "numeric", + "numericValue": 3969.135, + "numericUnit": "millisecond", + "displayValue": "4.0 s" + }, + "largest-contentful-paint": { + "id": "largest-contentful-paint", + "title": "Largest Contentful Paint", + "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn More](https://web.dev/lighthouse-largest-contentful-paint/)", + "score": 0.28, + "scoreDisplayMode": "numeric", + "numericValue": 4927.278, + "numericUnit": "millisecond", + "displayValue": "4.9 s" + }, + "first-meaningful-paint": { + "id": "first-meaningful-paint", + "title": "First Meaningful Paint", + "description": "First Meaningful Paint measures when the primary content of a page is visible. [Learn more](https://web.dev/first-meaningful-paint/).", + "score": 0.51, + "scoreDisplayMode": "numeric", + "numericValue": 3969.136, + "numericUnit": "millisecond", + "displayValue": "4.0 s" + }, + "load-fast-enough-for-pwa": { + "id": "load-fast-enough-for-pwa", + "title": "Page load is fast enough on mobile networks", + "description": "A fast page load over a cellular network ensures a good mobile user experience. [Learn more](https://web.dev/load-fast-enough-for-pwa/).", + "score": 1, + "scoreDisplayMode": "binary", + "numericValue": 4927.278, + "numericUnit": "millisecond" + }, + "speed-index": { + "id": "speed-index", + "title": "Speed Index", + "description": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more](https://web.dev/speed-index/).", + "score": 0.74, + "scoreDisplayMode": "numeric", + "numericValue": 4417, + "numericUnit": "millisecond", + "displayValue": "4.4 s" + }, + "screenshot-thumbnails": { + "id": "screenshot-thumbnails", + "title": "Screenshot Thumbnails", + "description": "This is what the load of your site looked like.", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "filmstrip", + "scale": 4927.278, + "items": [ + { + "timing": 493, + "timestamp": 185603812639.80002, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 985, + "timestamp": 185604305367.6, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 1478, + "timestamp": 185604798095.4, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 1971, + "timestamp": 185605290823.19998, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 2464, + "timestamp": 185605783551, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 2956, + "timestamp": 185606276278.80002, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 3449, + "timestamp": 185606769006.6, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 3942, + "timestamp": 185607261734.4, + "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRQBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIANUAeAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//Z" + }, + { + "timing": 4435, + "timestamp": 185607754462.19998, + "data": "data:image/jpeg;base64,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BcA634e/BXxh8PvH95cW2neCm8I6rFpcr2kQmSTRJbRDGYbOIxFJE2BQjl4yrMzFDnZQBy2jfs1ePdG8N6Bp4n8OvPpGh+KNNjLXc5jlfUbhZrVyBbj5RtAkGeAfl30AdX47+Bvijxl8XtE8YIuhWUNrqeg3lygupWldbFdSMuP3OC2+/UKDjKxkkqTtoA7/AOAHgTUvhf8ABXwb4S1h7STU9G06OymewkaSBig27kJVTg46FQR0oA7+gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA//9k=" + }, + { + "timing": 4927, + "timestamp": 185608247190, + "data": "data:image/jpeg;base64,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" + } + ] + } + }, + "final-screenshot": { + "id": "final-screenshot", + "title": "Final Screenshot", + "description": "The last screenshot captured of the pageload.", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "screenshot", + "timing": 4791, + "timestamp": 185608111383, + "data": "data:image/jpeg;base64,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" + } + }, + "estimated-input-latency": { + "id": "estimated-input-latency", + "title": "Estimated Input Latency", + "description": "Estimated Input Latency is an estimate of how long your app takes to respond to user input, in milliseconds, during the busiest 5s window of page load. If your latency is higher than 50 ms, users may perceive your app as laggy. [Learn more](https://web.dev/estimated-input-latency/).", + "score": 1, + "scoreDisplayMode": "numeric", + "numericValue": 16, + "numericUnit": "millisecond", + "displayValue": "20 ms" + }, + "total-blocking-time": { + "id": "total-blocking-time", + "title": "Total Blocking Time", + "description": "Sum of all time periods between FCP and Time to Interactive, when task length exceeded 50ms, expressed in milliseconds. [Learn more](https://web.dev/lighthouse-total-blocking-time/).", + "score": 1, + "scoreDisplayMode": "numeric", + "numericValue": 116.79800000000023, + "numericUnit": "millisecond", + "displayValue": "120 ms" + }, + "max-potential-fid": { + "id": "max-potential-fid", + "title": "Max Potential First Input Delay", + "description": "The maximum potential First Input Delay that your users could experience is the duration of the longest task. [Learn more](https://web.dev/lighthouse-max-potential-fid/).", + "score": 0.92, + "scoreDisplayMode": "numeric", + "numericValue": 122.537, + "numericUnit": "millisecond", + "displayValue": "120 ms" + }, + "cumulative-layout-shift": { + "id": "cumulative-layout-shift", + "title": "Cumulative Layout Shift", + "description": "Cumulative Layout Shift measures the movement of visible elements within the viewport. [Learn more](https://web.dev/cls/).", + "score": 0.23, + "scoreDisplayMode": "numeric", + "numericValue": 0.42, + "numericUnit": "unitless", + "displayValue": "0.42", + "details": { + "type": "debugdata", + "items": [ + { + "finalLayoutShiftTraceEventFound": true + } + ] + } + }, + "errors-in-console": { + "id": "errors-in-console", + "title": "Browser errors were logged to the console", + "description": "Errors logged to the console indicate unresolved problems. They can come from network request failures and other browser concerns. [Learn more](https://web.dev/errors-in-console/)", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "description", + "itemType": "code", + "text": "Description" + } + ], + "items": [ + { + "source": "other", + "description": "Application Cache Error event: Manifest fetch failed (404) http://localhost:10200/dobetterweb/clock.appcache", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + }, + { + "source": "Runtime.exception", + "description": "Error: An error\n at http://localhost:10200/dobetterweb/dbw_tester.html:42:38", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html" + }, + { + "source": "network", + "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" + }, + { + "source": "network", + "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", + "url": "http://localhost:10200/favicon.ico" + }, + { + "source": "network", + "description": "Failed to load resource: the server responded with a status of 404 (Not Found)", + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200" + } + ] + } + }, + "server-response-time": { + "id": "server-response-time", + "title": "Initial server response time was short", + "description": "Keep the server response time for the main document short because all other requests depend on it. [Learn more](https://web.dev/time-to-first-byte/).", + "score": 1, + "scoreDisplayMode": "binary", + "numericValue": 570.5630000000001, + "numericUnit": "millisecond", + "displayValue": "Root document took 570 ms", + "details": { + "type": "opportunity", + "headings": [ + { + "key": "url", + "valueType": "url", + "label": "URL" + }, + { + "key": "responseTime", + "valueType": "timespanMs", + "label": "Time Spent" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "responseTime": 570.5630000000001 + } + ], + "overallSavingsMs": 470.5630000000001 + } + }, + "first-cpu-idle": { + "id": "first-cpu-idle", + "title": "First CPU Idle", + "description": "First CPU Idle marks the first time at which the page's main thread is quiet enough to handle input. [Learn more](https://web.dev/first-cpu-idle/).", + "score": 0.72, + "scoreDisplayMode": "numeric", + "numericValue": 4927.278, + "numericUnit": "millisecond", + "displayValue": "4.9 s" + }, + "interactive": { + "id": "interactive", + "title": "Time to Interactive", + "description": "Time to interactive is the amount of time it takes for the page to become fully interactive. [Learn more](https://web.dev/interactive/).", + "score": 0.78, + "scoreDisplayMode": "numeric", + "numericValue": 4927.278, + "numericUnit": "millisecond", + "displayValue": "4.9 s" + }, + "user-timings": { + "id": "user-timings", + "title": "User Timing marks and measures", + "description": "Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences. [Learn more](https://web.dev/user-timings/).", + "score": null, + "scoreDisplayMode": "notApplicable", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "critical-request-chains": { + "id": "critical-request-chains", + "title": "Avoid chaining critical requests", + "description": "The Critical Request Chains below show you what resources are loaded with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. [Learn more](https://web.dev/critical-request-chains/).", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "12 chains found", + "details": { + "type": "criticalrequestchain", + "chains": { + "F3B687683512E0F003DD41EB23E2091A": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "startTime": 185603.321221, + "endTime": 185603.961376, + "responseReceivedTime": 185603.89718499998, + "transferSize": 12640 + }, + "children": { + "75994.3": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=100", + "startTime": 185603.956717, + "endTime": 185604.52588, + "responseReceivedTime": 185604.52470399998, + "transferSize": 821 + } + }, + "75994.4": { + "request": { + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "startTime": 185603.957861, + "endTime": 185604.534512, + "responseReceivedTime": 185604.532778, + "transferSize": 139 + } + }, + "75994.5": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=2200", + "startTime": 185603.959225, + "endTime": 185606.170588, + "responseReceivedTime": 185606.169761, + "transferSize": 821 + } + }, + "75994.6": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_disabled.css?delay=200&isdisabled", + "startTime": 185603.960011, + "endTime": 185604.541262, + "responseReceivedTime": 185604.54052399998, + "transferSize": 1108 + } + }, + "75994.7": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_partial_a.html?delay=200", + "startTime": 185603.961819, + "endTime": 185604.549739, + "responseReceivedTime": 185604.54903999998, + "transferSize": 736 + } + }, + "75994.8": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_partial_b.html?delay=200&isasync", + "startTime": 185603.962566, + "endTime": 185605.097653, + "responseReceivedTime": 185605.096858, + "transferSize": 733 + } + }, + "75994.9": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&async=true", + "startTime": 185603.964089, + "endTime": 185607.537382, + "responseReceivedTime": 185607.53660999998, + "transferSize": 821 + } + }, + "75994.10": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.js", + "startTime": 185603.965303, + "endTime": 185605.113307, + "responseReceivedTime": 185605.104776, + "transferSize": 1703 + } + }, + "75994.11": { + "request": { + "url": "http://localhost:10200/dobetterweb/empty_module.js?delay=500", + "startTime": 185603.96675, + "endTime": 185604.557407, + "responseReceivedTime": 185604.556719, + "transferSize": 144 + } + }, + "75994.21": { + "request": { + "url": "http://localhost:10200/zone.js", + "startTime": 185606.170955, + "endTime": 185607.28227, + "responseReceivedTime": 185606.742005, + "transferSize": 71654 + } + }, + "75994.22": { + "request": { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "startTime": 185607.195975, + "endTime": 185608.117509, + "responseReceivedTime": 185607.822806, + "transferSize": 30174 + } + }, + "75994.28": { + "request": { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?scriptActivated&delay=200", + "startTime": 185606.245562, + "endTime": 185607.285454, + "responseReceivedTime": 185606.82147599998, + "transferSize": 821 + } + } + } + } + }, + "longestChain": { + "duration": 4796.288000012282, + "length": 2, + "transferSize": 30174 + } + } + }, + "redirects": { + "id": "redirects", + "title": "Avoid multiple page redirects", + "description": "Redirects introduce additional delays before the page can be loaded. [Learn more](https://web.dev/redirects/).", + "score": 1, + "scoreDisplayMode": "numeric", + "numericValue": 0, + "numericUnit": "millisecond", + "displayValue": "", + "details": { + "type": "opportunity", + "headings": [], + "items": [], + "overallSavingsMs": 0 + } + }, + "installable-manifest": { + "id": "installable-manifest", + "title": "Web app manifest does not meet the installability requirements", + "description": "Browsers can proactively prompt users to add your app to their homescreen, which can lead to higher engagement. [Learn more](https://web.dev/installable-manifest/).", + "score": 0, + "scoreDisplayMode": "binary", + "explanation": "Failures: No manifest was fetched.", + "details": { + "type": "debugdata", + "items": [ + { + "failures": [ + "No manifest was fetched" + ], + "manifestUrl": null, + "isParseFailure": true, + "parseFailureReason": "No manifest was fetched" + } + ] + } + }, + "apple-touch-icon": { + "id": "apple-touch-icon", + "title": "Does not provide a valid `apple-touch-icon`", + "description": "For ideal appearance on iOS when users add a progressive web app to the home screen, define an `apple-touch-icon`. It must point to a non-transparent 192px (or 180px) square PNG. [Learn More](https://web.dev/apple-touch-icon/).", + "score": 0, + "scoreDisplayMode": "binary", + "warnings": [] + }, + "splash-screen": { + "id": "splash-screen", + "title": "Is not configured for a custom splash screen", + "description": "A themed splash screen ensures a high-quality experience when users launch your app from their homescreens. [Learn more](https://web.dev/splash-screen/).", + "score": 0, + "scoreDisplayMode": "binary", + "explanation": "Failures: No manifest was fetched.", + "details": { + "type": "debugdata", + "items": [ + { + "failures": [ + "No manifest was fetched" + ], + "isParseFailure": true, + "parseFailureReason": "No manifest was fetched" + } + ] + } + }, + "themed-omnibox": { + "id": "themed-omnibox", + "title": "Does not set a theme color for the address bar.", + "description": "The browser address bar can be themed to match your site. [Learn more](https://web.dev/themed-omnibox/).", + "score": 0, + "scoreDisplayMode": "binary", + "explanation": "Failures: No manifest was fetched,\nNo `` tag found.", + "details": { + "type": "debugdata", + "items": [ + { + "failures": [ + "No manifest was fetched", + "No `` tag found" + ], + "themeColor": null, + "isParseFailure": true, + "parseFailureReason": "No manifest was fetched" + } + ] + } + }, + "maskable-icon": { + "id": "maskable-icon", + "title": "Manifest doesn't have a maskable icon", + "description": "A maskable icon ensures that the image fills the entire shape without being letterboxed when installing the app on a device. [Learn more](https://web.dev/maskable-icon-audit/).", + "score": 0, + "scoreDisplayMode": "binary", + "explanation": "No manifest was fetched" + }, + "content-width": { + "id": "content-width", + "title": "Content is sized correctly for the viewport", + "description": "If the width of your app's content doesn't match the width of the viewport, your app might not be optimized for mobile screens. [Learn more](https://web.dev/content-width/).", + "score": 1, + "scoreDisplayMode": "binary" + }, + "image-aspect-ratio": { + "id": "image-aspect-ratio", + "title": "Displays images with incorrect aspect ratio", + "description": "Image display dimensions should match natural aspect ratio. [Learn more](https://web.dev/image-aspect-ratio/).", + "score": 0, + "scoreDisplayMode": "binary", + "warnings": [], + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "thumbnail", + "text": "" + }, + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "displayedAspectRatio", + "itemType": "text", + "text": "Aspect Ratio (Displayed)" + }, + { + "key": "actualAspectRatio", + "itemType": "text", + "text": "Aspect Ratio (Actual)" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/lighthouse-480x318.jpg", + "displayedAspectRatio": "480 x 57\n (8.42)", + "actualAspectRatio": "480 x 318\n (1.51)", + "doRatiosMatch": false + } + ] + } + }, + "image-size-responsive": { + "id": "image-size-responsive", + "title": "Serves images with low resolution", + "description": "Image natural dimensions should be proportional to the display size and the pixel ratio to maximize image clarity. [Learn more](https://web.dev/serve-responsive-images/).", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "thumbnail", + "text": "" + }, + { + "key": "elidedUrl", + "itemType": "url", + "text": "URL" + }, + { + "key": "displayedSize", + "itemType": "text", + "text": "Displayed size" + }, + { + "key": "actualSize", + "itemType": "text", + "text": "Actual size" + }, + { + "key": "expectedSize", + "itemType": "text", + "text": "Expected size" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/lighthouse-480x318.jpg", + "elidedUrl": "http://localhost:10200/dobetterweb/lighthouse-480x318.jpg", + "displayedSize": "480 x 318", + "actualSize": "480 x 318", + "actualPixels": 152640, + "expectedSize": "1260 x 835", + "expectedPixels": 1052100 + } + ] + } + }, + "preload-fonts": { + "id": "preload-fonts", + "title": "Fonts with `font-display: optional` are not preloaded", + "description": "Preload `optional` fonts so first-time visitors may use them. [Learn More](https://web.dev/preload-optional-fonts/)", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "URL" + } + ], + "items": [ + { + "url": "http://localhost:10503/perf/lobster-two-v10-latin-700.woff2?cors=true" + } + ] + } + }, + "deprecations": { + "id": "deprecations", + "title": "Uses deprecated APIs", + "description": "Deprecated APIs will eventually be removed from the browser. [Learn more](https://web.dev/deprecations/).", + "score": 0, + "scoreDisplayMode": "binary", + "displayValue": "3 warnings found", + "details": { + "type": "table", + "headings": [ + { + "key": "value", + "itemType": "text", + "text": "Deprecation / Warning" + }, + { + "key": "source", + "itemType": "source-location", + "text": "URL" + } + ], + "items": [ + { + "value": "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.", + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 322, + "column": 6 + } + }, + { + "value": "'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.", + "source": { + "type": "source-location", + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 325, + "column": 9 + } + }, + { + "value": "/deep/ combinator is no longer supported in CSS dynamic profile.It is now effectively no-op, acting as if it were a descendant combinator. /deep/ combinator will be removed, and will be invalid at M65. You should remove it. See https://www.chromestatus.com/features/4964279606312960 for more details." + } + ] + } + }, + "mainthread-work-breakdown": { + "id": "mainthread-work-breakdown", + "title": "Minimizes main-thread work", + "description": "Consider reducing the time spent parsing, compiling and executing JS. You may find delivering smaller JS payloads helps with this. [Learn more](https://web.dev/mainthread-work-breakdown/)", + "score": 0.96, + "scoreDisplayMode": "numeric", + "numericValue": 1548.5690000000002, + "numericUnit": "millisecond", + "displayValue": "1.5 s", + "details": { + "type": "table", + "headings": [ + { + "key": "groupLabel", + "itemType": "text", + "text": "Category" + }, + { + "key": "duration", + "itemType": "ms", + "granularity": 1, + "text": "Time Spent" + } + ], + "items": [ + { + "group": "scriptEvaluation", + "groupLabel": "Script Evaluation", + "duration": 1148.6240000000003 + }, + { + "group": "other", + "groupLabel": "Other", + "duration": 177.20099999999977 + }, + { + "group": "styleLayout", + "groupLabel": "Style & Layout", + "duration": 121.584 + }, + { + "group": "parseHTML", + "groupLabel": "Parse HTML & CSS", + "duration": 53.65500000000001 + }, + { + "group": "garbageCollection", + "groupLabel": "Garbage Collection", + "duration": 26.198999999999998 + }, + { + "group": "paintCompositeRender", + "groupLabel": "Rendering", + "duration": 13.486999999999998 + }, + { + "group": "scriptParseCompile", + "groupLabel": "Script Parsing & Compilation", + "duration": 7.818999999999999 + } + ] + } + }, + "bootup-time": { + "id": "bootup-time", + "title": "JavaScript execution time", + "description": "Consider reducing the time spent parsing, compiling, and executing JS. You may find delivering smaller JS payloads helps with this. [Learn more](https://web.dev/bootup-time/).", + "score": 0.92, + "scoreDisplayMode": "numeric", + "numericValue": 1150.5310000000002, + "numericUnit": "millisecond", + "displayValue": "1.2 s", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "total", + "granularity": 1, + "itemType": "ms", + "text": "Total CPU Time" + }, + { + "key": "scripting", + "granularity": 1, + "itemType": "ms", + "text": "Script Evaluation" + }, + { + "key": "scriptParseCompile", + "granularity": 1, + "itemType": "ms", + "text": "Script Parse" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "total": 1044.3820000000003, + "scripting": 963.7010000000001, + "scriptParseCompile": 2.777 + }, + { + "url": "Unattributable", + "total": 279.87100000000004, + "scripting": 9.61, + "scriptParseCompile": 0.092 + }, + { + "url": "http://localhost:10200/zone.js", + "total": 107.086, + "scripting": 90.81299999999999, + "scriptParseCompile": 1.674 + }, + { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "total": 90.363, + "scripting": 80.659, + "scriptParseCompile": 1.205 + } + ], + "summary": { + "wastedMs": 1150.5310000000002 + } + } + }, + "uses-rel-preload": { + "id": "uses-rel-preload", + "title": "Preload key requests", + "description": "Consider using `` to prioritize fetching resources that are currently requested later in page load. [Learn more](https://web.dev/uses-rel-preload/).", + "score": 1, + "scoreDisplayMode": "numeric", + "numericValue": 0, + "numericUnit": "millisecond", + "displayValue": "", + "details": { + "type": "opportunity", + "headings": [], + "items": [], + "overallSavingsMs": 0 + } + }, + "uses-rel-preconnect": { + "id": "uses-rel-preconnect", + "title": "Preconnect to required origins", + "description": "Consider adding `preconnect` or `dns-prefetch` resource hints to establish early connections to important third-party origins. [Learn more](https://web.dev/uses-rel-preconnect/).", + "score": 1, + "scoreDisplayMode": "numeric", + "numericValue": 0, + "numericUnit": "millisecond", + "displayValue": "", + "warnings": [], + "details": { + "type": "opportunity", + "headings": [], + "items": [], + "overallSavingsMs": 0 + } + }, + "font-display": { + "id": "font-display", + "title": "All text remains visible during webfont loads", + "description": "Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading. [Learn more](https://web.dev/font-display/).", + "score": 1, + "scoreDisplayMode": "binary", + "warnings": [], + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "diagnostics": { + "id": "diagnostics", + "title": "Diagnostics", + "description": "Collection of useful page vitals.", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "debugdata", + "items": [ + { + "numRequests": 18, + "numScripts": 4, + "numStylesheets": 7, + "numFonts": 0, + "numTasks": 107, + "numTasksOver10ms": 7, + "numTasksOver25ms": 5, + "numTasksOver50ms": 4, + "numTasksOver100ms": 3, + "numTasksOver500ms": 1, + "rtt": 0.8639999999999999, + "throughput": 1398339.461891128, + "maxRtt": 1.7249999999999943, + "maxServerLatency": 572.829, + "totalByteWeight": 160738, + "totalTaskTime": 1548.5690000000002, + "mainDocumentTransferSize": 12640 + } + ] + } + }, + "network-requests": { + "id": "network-requests", + "title": "Network Requests", + "description": "Lists the network requests that were made during page load.", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "protocol", + "itemType": "text", + "text": "Protocol" + }, + { + "key": "startTime", + "itemType": "ms", + "granularity": 1, + "text": "Start Time" + }, + { + "key": "endTime", + "itemType": "ms", + "granularity": 1, + "text": "End Time" + }, + { + "key": "transferSize", + "itemType": "bytes", + "displayUnit": "kb", + "granularity": 1, + "text": "Transfer Size" + }, + { + "key": "resourceSize", + "itemType": "bytes", + "displayUnit": "kb", + "granularity": 1, + "text": "Resource Size" + }, + { + "key": "statusCode", + "itemType": "text", + "text": "Status Code" + }, + { + "key": "mimeType", + "itemType": "text", + "text": "MIME Type" + }, + { + "key": "resourceType", + "itemType": "text", + "text": "Resource Type" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "protocol": "http/1.1", + "startTime": 0, + "endTime": 640.1550000009593, + "finished": true, + "transferSize": 12640, + "resourceSize": 12519, + "statusCode": 200, + "mimeType": "text/html", + "resourceType": "Document" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=2000&async=true", + "protocol": "http/1.1", + "startTime": 630.2950000099372, + "endTime": 2635.035000013886, + "finished": true, + "transferSize": 821, + "resourceSize": 677, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=100", + "protocol": "http/1.1", + "startTime": 635.496000002604, + "endTime": 1204.6590000099968, + "finished": true, + "transferSize": 821, + "resourceSize": 677, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/unknown404.css?delay=200", + "protocol": "http/1.1", + "startTime": 636.6400000115391, + "endTime": 1213.2910000218544, + "finished": true, + "transferSize": 139, + "resourceSize": 0, + "statusCode": 404, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=2200", + "protocol": "http/1.1", + "startTime": 638.0040000076406, + "endTime": 2849.3670000170823, + "finished": true, + "transferSize": 821, + "resourceSize": 677, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_disabled.css?delay=200&isdisabled", + "protocol": "http/1.1", + "startTime": 638.7899999972433, + "endTime": 1220.04100002232, + "finished": true, + "transferSize": 1108, + "resourceSize": 964, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_partial_a.html?delay=200", + "protocol": "http/1.1", + "startTime": 640.5979999981355, + "endTime": 1228.5180000180844, + "finished": true, + "transferSize": 736, + "resourceSize": 616, + "statusCode": 200, + "mimeType": "text/html", + "resourceType": "Document" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_partial_b.html?delay=200&isasync", + "protocol": "http/1.1", + "startTime": 641.3450000109151, + "endTime": 1776.4320000133011, + "finished": true, + "transferSize": 733, + "resourceSize": 613, + "statusCode": 200, + "mimeType": "text/html", + "resourceType": "Document" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&async=true", + "protocol": "http/1.1", + "startTime": 642.8679999953602, + "endTime": 4216.161000018474, + "finished": true, + "transferSize": 821, + "resourceSize": 677, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.js", + "protocol": "http/1.1", + "startTime": 644.0820000134408, + "endTime": 1792.0860000012908, + "finished": true, + "transferSize": 1703, + "resourceSize": 1552, + "statusCode": 200, + "mimeType": "text/javascript", + "resourceType": "Script" + }, + { + "url": "http://localhost:10200/dobetterweb/empty_module.js?delay=500", + "protocol": "http/1.1", + "startTime": 645.529000001261, + "endTime": 1236.1859999946319, + "finished": true, + "transferSize": 144, + "resourceSize": 0, + "statusCode": 200, + "mimeType": "text/javascript", + "resourceType": "Script" + }, + { + "url": "http://localhost:10200/dobetterweb/lighthouse-480x318.jpg", + "protocol": "http/1.1", + "startTime": 3951.6250000160653, + "endTime": 4779.641000000993, + "finished": true, + "transferSize": 24741, + "resourceSize": 24620, + "statusCode": 200, + "mimeType": "image/jpeg", + "resourceType": "Image" + }, + { + "url": "http://localhost:10200/zone.js", + "protocol": "http/1.1", + "startTime": 2849.7340000176337, + "endTime": 3961.049000005005, + "finished": true, + "transferSize": 71654, + "resourceSize": 71501, + "statusCode": 200, + "mimeType": "text/javascript", + "resourceType": "Script" + }, + { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "protocol": "http/1.1", + "startTime": 3874.7540000185836, + "endTime": 4796.288000012282, + "finished": true, + "transferSize": 30174, + "resourceSize": 84245, + "statusCode": 200, + "mimeType": "text/javascript", + "resourceType": "Script" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.css?scriptActivated&delay=200", + "protocol": "http/1.1", + "startTime": 2924.34100000537, + "endTime": 3964.233000006061, + "finished": true, + "transferSize": 821, + "resourceSize": 677, + "statusCode": 200, + "mimeType": "text/css", + "resourceType": "Stylesheet" + }, + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.html", + "protocol": "http/1.1", + "startTime": 3066.252999997232, + "endTime": 3772.7560000203084, + "finished": true, + "transferSize": 12640, + "resourceSize": 12519, + "statusCode": 200, + "mimeType": "text/html", + "resourceType": "XHR" + }, + { + "url": "blob:http://localhost:10200/ae0eac03-ab9b-4a6a-b299-f5212153e277", + "protocol": "blob", + "startTime": 3829.6360000094865, + "endTime": 3968.59800000675, + "finished": true, + "transferSize": 0, + "resourceSize": 4, + "statusCode": 200, + "mimeType": "text/plain", + "resourceType": "Image" + }, + { + "url": "http://localhost:10200/favicon.ico", + "protocol": "http/1.1", + "startTime": 4967.373000021325, + "endTime": 5536.498000001302, + "finished": true, + "transferSize": 221, + "resourceSize": 95, + "statusCode": 404, + "mimeType": "text/plain", + "resourceType": "Other" + } + ] + } + }, + "network-rtt": { + "id": "network-rtt", + "title": "Network Round Trip Times", + "description": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. [Learn more](https://hpbn.co/primer-on-latency-and-bandwidth/).", + "score": null, + "scoreDisplayMode": "informative", + "numericValue": 1.7249999999999943, + "numericUnit": "millisecond", + "displayValue": "0 ms", + "details": { + "type": "table", + "headings": [ + { + "key": "origin", + "itemType": "text", + "text": "URL" + }, + { + "key": "rtt", + "itemType": "ms", + "granularity": 1, + "text": "Time Spent" + } + ], + "items": [ + { + "origin": "http://ajax.googleapis.com", + "rtt": 1.7249999999999943 + }, + { + "origin": "http://localhost:10200", + "rtt": 0.8639999999999999 + } + ] + } + }, + "network-server-latency": { + "id": "network-server-latency", + "title": "Server Backend Latencies", + "description": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. [Learn more](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall).", + "score": null, + "scoreDisplayMode": "informative", + "numericValue": 572.829, + "numericUnit": "millisecond", + "displayValue": "570 ms", + "details": { + "type": "table", + "headings": [ + { + "key": "origin", + "itemType": "text", + "text": "URL" + }, + { + "key": "serverResponseTime", + "itemType": "ms", + "granularity": 1, + "text": "Time Spent" + } + ], + "items": [ + { + "origin": "http://localhost:10200", + "serverResponseTime": 572.829 + }, + { + "origin": "http://ajax.googleapis.com", + "serverResponseTime": 562.398 + } + ] + } + }, + "main-thread-tasks": { + "id": "main-thread-tasks", + "title": "Tasks", + "description": "Lists the toplevel main thread tasks that executed during page load.", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "table", + "headings": [ + { + "key": "startTime", + "itemType": "ms", + "granularity": 1, + "text": "Start Time" + }, + { + "key": "duration", + "itemType": "ms", + "granularity": 1, + "text": "End Time" + } + ], + "items": [ + { + "duration": 5.272, + "startTime": 598.738 + }, + { + "duration": 26.926, + "startTime": 604.035 + }, + { + "duration": 6.681, + "startTime": 630.994 + }, + { + "duration": 19.718, + "startTime": 637.706 + }, + { + "duration": 7.812, + "startTime": 666.147 + }, + { + "duration": 10.087, + "startTime": 2639.59 + }, + { + "duration": 983.081, + "startTime": 2854.095 + }, + { + "duration": 123.752, + "startTime": 3839.839 + }, + { + "duration": 5.338, + "startTime": 3980.383 + }, + { + "duration": 6.574, + "startTime": 3986.1 + }, + { + "duration": 96.198, + "startTime": 3996.134 + }, + { + "duration": 9.23, + "startTime": 4098.379 + }, + { + "duration": 5.463, + "startTime": 4784.783 + }, + { + "duration": 127.282, + "startTime": 4808.602 + }, + { + "duration": 6.885, + "startTime": 8603.411 + }, + { + "duration": 7.258, + "startTime": 10219.292 + } + ] + } + }, + "metrics": { + "id": "metrics", + "title": "Metrics", + "description": "Collects all available metrics.", + "score": null, + "scoreDisplayMode": "informative", + "numericValue": 4927, + "numericUnit": "millisecond", + "details": { + "type": "debugdata", + "items": [ + { + "firstContentfulPaint": 3969, + "firstContentfulPaintTs": 185607289047, + "firstMeaningfulPaint": 3969, + "firstMeaningfulPaintTs": 185607289048, + "largestContentfulPaint": 4927, + "largestContentfulPaintTs": 185608247190, + "firstCPUIdle": 4927, + "firstCPUIdleTs": 185608247190, + "interactive": 4927, + "interactiveTs": 185608247190, + "speedIndex": 4417, + "speedIndexTs": 185607736912, + "estimatedInputLatency": 16, + "totalBlockingTime": 117, + "maxPotentialFID": 123, + "cumulativeLayoutShift": 0.42, + "observedTimeOrigin": 0, + "observedTimeOriginTs": 185603319912, + "observedNavigationStart": 0, + "observedNavigationStartTs": 185603319912, + "observedFirstPaint": 3969, + "observedFirstPaintTs": 185607289043, + "observedFirstContentfulPaint": 3969, + "observedFirstContentfulPaintTs": 185607289047, + "observedFirstMeaningfulPaint": 3969, + "observedFirstMeaningfulPaintTs": 185607289048, + "observedLargestContentfulPaint": 4927, + "observedLargestContentfulPaintTs": 185608247190, + "observedTraceEnd": 10281, + "observedTraceEndTs": 185613601189, + "observedLoad": 4924, + "observedLoadTs": 185608244374, + "observedDomContentLoaded": 4901, + "observedDomContentLoadedTs": 185608220734, + "observedCumulativeLayoutShift": 0.42, + "observedFirstVisualChange": 3969, + "observedFirstVisualChangeTs": 185607288912, + "observedLastVisualChange": 4791, + "observedLastVisualChangeTs": 185608110912, + "observedSpeedIndex": 4417, + "observedSpeedIndexTs": 185607736763 + }, + { + "lcpInvalidated": false + } + ] + } + }, + "offline-start-url": { + "id": "offline-start-url", + "title": "`start_url` does not respond with a 200 when offline", + "description": "A service worker enables your web app to be reliable in unpredictable network conditions. [Learn more](https://web.dev/offline-start-url/).", + "score": 0, + "scoreDisplayMode": "binary", + "explanation": "No usable web app manifest found on page.", + "warnings": [] + }, + "performance-budget": { + "id": "performance-budget", + "title": "Performance budget", + "description": "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).", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "table", + "headings": [ + { + "key": "label", + "itemType": "text", + "text": "Resource Type" + }, + { + "key": "requestCount", + "itemType": "numeric", + "text": "Requests" + }, + { + "key": "transferSize", + "itemType": "bytes", + "text": "Transfer Size" + }, + { + "key": "countOverBudget", + "itemType": "text", + "text": "" + }, + { + "key": "sizeOverBudget", + "itemType": "bytes", + "text": "Over Budget" + } + ], + "items": [ + { + "resourceType": "script", + "label": "Script", + "requestCount": 4, + "transferSize": 103675, + "countOverBudget": "2 requests", + "sizeOverBudget": 72955 + }, + { + "resourceType": "total", + "label": "Total", + "requestCount": 16, + "transferSize": 160517, + "countOverBudget": "6 requests", + "sizeOverBudget": 58117 + }, + { + "resourceType": "other", + "label": "Other", + "requestCount": 1, + "transferSize": 12640, + "sizeOverBudget": 7520 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "requestCount": 1, + "transferSize": 30174, + "sizeOverBudget": 4574 + }, + { + "resourceType": "stylesheet", + "label": "Stylesheet", + "requestCount": 7, + "transferSize": 5352, + "countOverBudget": "5 requests", + "sizeOverBudget": 232 + }, + { + "resourceType": "image", + "label": "Image", + "requestCount": 1, + "transferSize": 24741 + }, + { + "resourceType": "media", + "label": "Media", + "requestCount": 0, + "transferSize": 0 + }, + { + "resourceType": "font", + "label": "Font", + "requestCount": 0, + "transferSize": 0 + }, + { + "resourceType": "document", + "label": "Document", + "requestCount": 3, + "transferSize": 14109, + "countOverBudget": "2 requests" + } + ] + } + }, + "timing-budget": { + "id": "timing-budget", + "title": "Timing budget", + "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).", + "score": null, + "scoreDisplayMode": "informative", + "details": { + "type": "table", + "headings": [ + { + "key": "label", + "itemType": "text", + "text": "Metric" + }, + { + "key": "measurement", + "itemType": "ms", + "text": "Measurement" + }, + { + "key": "overBudget", + "itemType": "ms", + "text": "Over Budget" + } + ], + "items": [ + { + "metric": "first-cpu-idle", + "label": "First CPU Idle", + "measurement": 4927, + "overBudget": 2027 + }, + { + "metric": "interactive", + "label": "Time to Interactive", + "measurement": 4927, + "overBudget": 2027 + }, + { + "metric": "first-meaningful-paint", + "label": "First Meaningful Paint", + "measurement": 3969, + "overBudget": 1969 + }, + { + "metric": "first-contentful-paint", + "label": "First Contentful Paint", + "measurement": 3969, + "overBudget": 969 + }, + { + "metric": "max-potential-fid", + "label": "Max Potential First Input Delay", + "measurement": 123, + "overBudget": 23 + } + ] + } + }, + "resource-summary": { + "id": "resource-summary", + "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. [Learn more](https://web.dev/use-lighthouse-for-performance-budgets/).", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "16 requests • 157 KiB", + "details": { + "type": "table", + "headings": [ + { + "key": "label", + "itemType": "text", + "text": "Resource Type" + }, + { + "key": "requestCount", + "itemType": "numeric", + "text": "Requests" + }, + { + "key": "transferSize", + "itemType": "bytes", + "text": "Transfer Size" + } + ], + "items": [ + { + "resourceType": "total", + "label": "Total", + "requestCount": 16, + "transferSize": 160517 + }, + { + "resourceType": "script", + "label": "Script", + "requestCount": 4, + "transferSize": 103675 + }, + { + "resourceType": "image", + "label": "Image", + "requestCount": 1, + "transferSize": 24741 + }, + { + "resourceType": "document", + "label": "Document", + "requestCount": 3, + "transferSize": 14109 + }, + { + "resourceType": "other", + "label": "Other", + "requestCount": 1, + "transferSize": 12640 + }, + { + "resourceType": "stylesheet", + "label": "Stylesheet", + "requestCount": 7, + "transferSize": 5352 + }, + { + "resourceType": "media", + "label": "Media", + "requestCount": 0, + "transferSize": 0 + }, + { + "resourceType": "font", + "label": "Font", + "requestCount": 0, + "transferSize": 0 + }, + { + "resourceType": "third-party", + "label": "Third-party", + "requestCount": 1, + "transferSize": 30174 + } + ] + } + }, + "third-party-summary": { + "id": "third-party-summary", + "title": "Minimize third-party usage", + "description": "Third-party code can significantly impact load performance. Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/).", + "score": 1, + "scoreDisplayMode": "binary", + "displayValue": "Third-party code blocked the main thread for 20 ms", + "details": { + "type": "table", + "headings": [ + { + "key": "entity", + "itemType": "link", + "text": "Third-Party", + "subItemsHeading": { + "key": "url", + "itemType": "url" + } + }, + { + "key": "transferSize", + "granularity": 1, + "itemType": "bytes", + "text": "Transfer Size", + "subItemsHeading": { + "key": "transferSize" + } + }, + { + "key": "blockingTime", + "granularity": 1, + "itemType": "ms", + "text": "Main-Thread Blocking Time", + "subItemsHeading": { + "key": "blockingTime" + } + } + ], + "items": [ + { + "mainThreadTime": 90.36300000000001, + "blockingTime": 22.918000000000006, + "transferSize": 30174, + "entity": { + "type": "link", + "text": "Google CDN", + "url": "https://developers.google.com/speed/libraries/" + }, + "subItems": { + "type": "subitems", + "items": [ + { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "mainThreadTime": 90.36300000000001, + "blockingTime": 22.918000000000006, + "transferSize": 30174 + } + ] + } + } + ], + "summary": { + "wastedBytes": 30174, + "wastedMs": 22.918000000000006 + } + } + }, + "largest-contentful-paint-element": { + "id": "largest-contentful-paint-element", + "title": "Largest Contentful Paint element", + "description": "This is the largest contentful element painted within the viewport. [Learn More](https://web.dev/lighthouse-largest-contentful-paint/)", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "1 element found", + "details": { + "type": "table", + "headings": [ + { + "key": "node", + "itemType": "node", + "text": "Element" + } + ], + "items": [ + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,0,DIV,1,P", + "selector": "body > div > p", + "nodeLabel": "This domain is for use in illustrative examples in documents. You may use this …", + "snippet": "

" + } + } + ] + } + }, + "layout-shift-elements": { + "id": "layout-shift-elements", + "title": "Avoid large layout shifts", + "description": "These DOM elements contribute most to the CLS of the page.", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "4 elements found", + "details": { + "type": "table", + "headings": [ + { + "key": "node", + "itemType": "node", + "text": "Element" + }, + { + "key": "score", + "itemType": "numeric", + "granularity": 0.001, + "text": "CLS Contribution" + } + ], + "items": [ + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,2,DIV,0,DIV,0,DIV,0,ARTICLE,1,DIV,3,H5", + "selector": "div.blog-index > article > div.entry-content > h5", + "nodeLabel": "Debugging Node.js with Chrome DevTools", + "snippet": "

" + } + }, + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,2,DIV,0,DIV,0,DIV,0,ARTICLE,1,DIV,4,P", + "selector": "div.blog-index > article > div.entry-content > p", + "nodeLabel": "The canonical guide to using the Chrome DevTools UI for debugging Node.js. It d…", + "snippet": "

" + } + }, + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,2,DIV,0,DIV,0,DIV,0,ARTICLE,1,DIV,5,HR", + "selector": "div.blog-index > article > div.entry-content > hr", + "nodeLabel": "hr", + "snippet": "


" + } + }, + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,2,DIV,0,DIV,0,DIV,0,ARTICLE,1,DIV,6,P", + "selector": "div.blog-index > article > div.entry-content > p", + "nodeLabel": "Aside from that, I’ve been busy working on Lighthouse, performance metrics, too…", + "snippet": "

" + } + } + ] + } + }, + "long-tasks": { + "id": "long-tasks", + "title": "Avoid long main-thread tasks", + "description": "Lists the longest tasks on the main thread, useful for identifying worst contributors to input delay. [Learn more](https://web.dev/long-tasks-devtools/)", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "4 long tasks found", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "startTime", + "itemType": "ms", + "granularity": 1, + "text": "Start Time" + }, + { + "key": "duration", + "itemType": "ms", + "granularity": 1, + "text": "Duration" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/dbw_tester.js", + "duration": 983.081, + "startTime": 2854.095 + }, + { + "url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", + "duration": 127.282, + "startTime": 4808.602 + }, + { + "url": "Unattributable", + "duration": 123.752, + "startTime": 3839.839 + }, + { + "url": "http://localhost:10200/zone.js", + "duration": 96.198, + "startTime": 3996.134 + } + ] + } + }, + "no-unload-listeners": { + "id": "no-unload-listeners", + "title": "Registers an `unload` listener", + "description": "The `unload` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache. Consider using the `pagehide` or `visibilitychange` events instead. [Learn More](https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event)", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "source", + "itemType": "source-location", + "text": "URL" + } + ], + "items": [ + { + "source": { + "type": "source-location", + "url": "http://localhost:58599/dobetterweb/dbw_tester.html", + "urlProvider": "network", + "line": 386, + "column": 36 + } + } + ] + } + }, + "non-composited-animations": { + "id": "non-composited-animations", + "title": "Avoid non-composited animations", + "description": "Animations which are not composited can be janky and increase CLS. [Learn more](https://web.dev/non-composited-animations)", + "score": null, + "scoreDisplayMode": "informative", + "displayValue": "1 animated element found", + "details": { + "type": "table", + "headings": [ + { + "key": "node", + "itemType": "node", + "subItemsHeading": { + "key": "failureReason", + "itemType": "text" + }, + "text": "Element" + }, + { + "key": null, + "itemType": "text", + "subItemsHeading": { + "key": "animation", + "itemType": "text" + }, + "text": "Name" + } + ], + "items": [ + { + "node": { + "type": "node", + "path": "1,HTML,1,BODY,0,DIV", + "selector": "body > div#animated-boi", + "nodeLabel": "div", + "snippet": "

" + }, + "subItems": { + "type": "subitems", + "items": [ + { + "failureReason": "Unsupported CSS Property: width" + }, + { + "failureReason": "Unsupported CSS Properties: height, left", + "animation": "alpha" + }, + { + "failureReason": "Unsupported CSS Property: background-color", + "animation": "beta" + } + ] + } + } + ] + } + }, + "unsized-images": { + "id": "unsized-images", + "title": "Image elements do not have explicit `width` and `height`", + "description": "Set an explicit width and height on image elements to reduce layout shifts and improve CLS. [Learn more](https://web.dev/optimize-cls/#images-without-dimensions)", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "url", + "itemType": "thumbnail", + "text": "" + }, + { + "key": "url", + "itemType": "url", + "text": "URL" + }, + { + "key": "node", + "itemType": "node", + "text": "Failing Elements" + } + ], + "items": [ + { + "url": "http://localhost:10200/dobetterweb/lighthouse-480x318.jpg", + "node": { + "type": "node" + } + } + ] + } + }, + "valid-source-maps": { + "id": "valid-source-maps", + "title": "Page has valid source maps", + "description": "Source maps translate minified code to the original source code. This helps developers debug in production. In addition, Lighthouse is able to provide further insights. Consider deploying source maps to take advantage of these benefits. [Learn more](https://developers.google.com/web/tools/chrome-devtools/javascript/source-maps).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "pwa-cross-browser": { + "id": "pwa-cross-browser", + "title": "Site works cross-browser", + "description": "To reach the most number of users, sites should work across every major browser. [Learn more](https://web.dev/pwa-cross-browser/).", + "score": null, + "scoreDisplayMode": "manual" + }, + "pwa-page-transitions": { + "id": "pwa-page-transitions", + "title": "Page transitions don't feel like they block on the network", + "description": "Transitions should feel snappy as you tap around, even on a slow network. This experience is key to a user's perception of performance. [Learn more](https://web.dev/pwa-page-transitions/).", + "score": null, + "scoreDisplayMode": "manual" + }, + "pwa-each-page-has-url": { + "id": "pwa-each-page-has-url", + "title": "Each page has a URL", + "description": "Ensure individual pages are deep linkable via URL and that URLs are unique for the purpose of shareability on social media. [Learn more](https://web.dev/pwa-each-page-has-url/).", + "score": null, + "scoreDisplayMode": "manual" + }, + "accesskeys": { + "id": "accesskeys", + "title": "`[accesskey]` values are unique", + "description": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://web.dev/accesskeys/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, + "aria-allowed-attr": { + "id": "aria-allowed-attr", + "title": "`[aria-*]` attributes match their roles", + "description": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://web.dev/aria-allowed-attr/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-hidden-body": { + "id": "aria-hidden-body", + "title": "`[aria-hidden=\"true\"]` is not present on the document ``", + "description": "Assistive technologies, like screen readers, work inconsistently when `aria-hidden=\"true\"` is set on the document ``. [Learn more](https://web.dev/aria-hidden-body/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-hidden-focus": { + "id": "aria-hidden-focus", + "title": "`[aria-hidden=\"true\"]` elements do not contain focusable descendents", + "description": "Focusable descendents within an `[aria-hidden=\"true\"]` element prevent those interactive elements from being available to users of assistive technologies like screen readers. [Learn more](https://web.dev/aria-hidden-focus/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, + "aria-input-field-name": { + "id": "aria-input-field-name", + "title": "ARIA input fields have accessible names", + "description": "When an input field doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. [Learn more](https://web.dev/aria-input-field-name/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, + "aria-required-attr": { + "id": "aria-required-attr", + "title": "`[role]`s have all required `[aria-*]` attributes", + "description": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://web.dev/aria-required-attr/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-required-children": { + "id": "aria-required-children", + "title": "Elements with an ARIA `[role]` that require children to contain a specific `[role]` have all required children.", + "description": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://web.dev/aria-required-children/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-required-parent": { + "id": "aria-required-parent", + "title": "`[role]`s are contained by their required parent element", + "description": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://web.dev/aria-required-parent/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-roles": { + "id": "aria-roles", + "title": "`[role]` values are valid", + "description": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://web.dev/aria-roles/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-toggle-field-name": { + "id": "aria-toggle-field-name", + "title": "ARIA toggle fields have accessible names", + "description": "When a toggle field doesn't have an accessible name, screen readers announce it with a generic name, making it unusable for users who rely on screen readers. [Learn more](https://web.dev/aria-toggle-field-name/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, + "aria-valid-attr-value": { + "id": "aria-valid-attr-value", + "title": "`[aria-*]` attributes have valid values", + "description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://web.dev/aria-valid-attr-value/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "aria-valid-attr": { + "id": "aria-valid-attr", + "title": "`[aria-*]` attributes are valid and not misspelled", + "description": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://web.dev/aria-valid-attr/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "button-name": { + "id": "button-name", + "title": "Buttons have an accessible name", + "description": "When a button doesn't have an accessible name, screen readers announce it as \"button\", making it unusable for users who rely on screen readers. [Learn more](https://web.dev/button-name/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "bypass": { + "id": "bypass", + "title": "The page contains a heading, skip link, or landmark region", + "description": "Adding ways to bypass repetitive content lets keyboard users navigate the page more efficiently. [Learn more](https://web.dev/bypass/).", + "score": 1, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [], + "items": [] + } + }, + "color-contrast": { + "id": "color-contrast", + "title": "Background and foreground colors do not have a sufficient contrast ratio.", + "description": "Low-contrast text is difficult or impossible for many users to read. [Learn more](https://web.dev/color-contrast/).", + "score": 0, + "scoreDisplayMode": "binary", + "details": { + "type": "table", + "headings": [ + { + "key": "node", + "itemType": "node", + "text": "Failing Elements" + } + ], + "items": [ + { + "node": { + "type": "node", + "selector": "body > div > h2", + "path": "3,HTML,1,BODY,7,DIV,0,H2", + "snippet": "

", + "boundingRect": { + "top": 336, + "bottom": 364, + "left": 8, + "right": 352, + "width": 344, + "height": 28 + }, + "explanation": "Fix any of the following:\n Element has insufficient color contrast of 1.32 (foreground color: #ffc0cb, background color: #eeeeee, font size: 18.0pt (24px), font weight: bold). Expected contrast ratio of 3:1", + "nodeLabel": "Do better web tester page" + } + }, + { + "node": { + "type": "node", + "selector": "body > div > span", + "path": "3,HTML,1,BODY,7,DIV,1,SPAN", + "snippet": "", + "boundingRect": { + "top": 384, + "bottom": 402, + "left": 8, + "right": 65, + "width": 57, + "height": 18 + }, + "explanation": "Fix any of the following:\n Element has insufficient color contrast of 1.32 (foreground color: #ffc0cb, background color: #eeeeee, font size: 12.0pt (16px), font weight: normal). Expected contrast ratio of 4.5:1", + "nodeLabel": "Hi there!" + } + } + ], + "debugData": { + "type": "debugdata", + "impact": "serious", + "tags": [ + "cat.color", + "wcag2aa", + "wcag143" + ] + } + } + }, + "definition-list": { + "id": "definition-list", + "title": "`
`'s contain only properly-ordered `
` and `
` groups, `