Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

new_audit: third party facades #11290

Merged
merged 90 commits into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
fa4ef82
starting shell
adamraine Aug 17, 2020
f7a73ca
basic audit
adamraine Aug 19, 2020
5204114
update sample (yikes)
adamraine Aug 19, 2020
4e68d60
license
adamraine Aug 19, 2020
812d217
Merge branch 'master' into lazy-third-party
adamraine Aug 20, 2020
3740ba1
remove code duplication
adamraine Aug 20, 2020
e600084
update sample
adamraine Aug 20, 2020
585aa8b
nit
adamraine Aug 20, 2020
94c1487
define lazy loading
adamraine Aug 20, 2020
339213f
Merge branch 'lazy-third-party' of github.com:GoogleChrome/lighthouse…
adamraine Aug 20, 2020
ffd6077
fix typo
adamraine Aug 20, 2020
6fec26f
add test cases
adamraine Aug 20, 2020
6eba114
hide third party ui filter
adamraine Aug 20, 2020
4dc8993
add temporary learn more link
adamraine Aug 20, 2020
597fdd0
update snapshot
adamraine Aug 20, 2020
30397ec
add displayValue to test
adamraine Aug 20, 2020
3c622da
use entity related resources
adamraine Aug 24, 2020
912e8d3
switch to product based report
adamraine Aug 24, 2020
b916432
move to experimental
adamraine Aug 24, 2020
ef46796
Merge branch 'master' into lazy-third-party
adamraine Aug 24, 2020
c59d76a
update sample and snapshot
adamraine Aug 24, 2020
34648e8
fix start end time bug
adamraine Aug 24, 2020
6ff862c
update sample
adamraine Aug 24, 2020
05450bd
Remove unnecessary typedef
adamraine Aug 24, 2020
79a2982
fix timing start bug
adamraine Aug 26, 2020
707fe72
move to default config
adamraine Aug 26, 2020
fdefa48
update sample
adamraine Aug 26, 2020
2a1284e
update index snapshot
adamraine Aug 26, 2020
ad69849
nits
adamraine Sep 9, 2020
7c6dc12
definitions
adamraine Sep 9, 2020
b17c292
add smoke test
adamraine Sep 9, 2020
4d56357
nits
adamraine Sep 11, 2020
acb984a
two pass
adamraine Sep 11, 2020
b609197
fix timing bugs
adamraine Sep 15, 2020
fce91cd
nits
adamraine Sep 15, 2020
c2f07e2
update test case structure
adamraine Sep 15, 2020
fe3246e
add test case
adamraine Sep 15, 2020
bae311b
the big rename
adamraine Sep 15, 2020
612c933
update sample and snapshot
adamraine Sep 15, 2020
1d47eaa
add real trace test case
adamraine Sep 15, 2020
446f2d3
update smoke test
adamraine Sep 15, 2020
085fb7e
smoke
adamraine Sep 15, 2020
c3f7198
Merge branch 'master' into lazy-third-party
adamraine Sep 15, 2020
812affa
revert
adamraine Sep 16, 2020
db17a66
update devtools web tests
adamraine Sep 16, 2020
4eb7481
change to category column
adamraine Sep 17, 2020
4229b06
move category to first column
adamraine Sep 21, 2020
4c1d528
type check
adamraine Sep 21, 2020
236fb9b
update description
adamraine Sep 21, 2020
3008fa8
add strings
adamraine Sep 22, 2020
26c463b
update strings
adamraine Sep 22, 2020
974491c
rebaseline devtools
adamraine Sep 22, 2020
b22afdd
Merge branch 'master' into lazy-third-party
adamraine Sep 24, 2020
5e5179a
rebaseline devtools
adamraine Sep 29, 2020
36ea5aa
rebaseline devtools
adamraine Oct 1, 2020
fb8b5a3
cleanup
adamraine Oct 1, 2020
aa30702
rename cutoff
adamraine Oct 1, 2020
8c86174
more cleanup
adamraine Oct 1, 2020
c30bf61
Merge branch 'master' into lazy-third-party
adamraine Oct 1, 2020
088f73c
identify first resource in LH
adamraine Oct 5, 2020
703bd72
rename firstEndTime
adamraine Oct 5, 2020
5bee091
update sample
adamraine Oct 5, 2020
b9328f3
condense last row
adamraine Oct 6, 2020
8ae6608
use entire entity
adamraine Oct 6, 2020
fda9948
update sample
adamraine Oct 6, 2020
fd97c9e
updates sample again
adamraine Oct 6, 2020
572a4e3
small nit
adamraine Oct 6, 2020
d4a792d
small nit 2
adamraine Oct 6, 2020
2bbaf12
update tpw
adamraine Oct 6, 2020
9396979
remove entity summary
adamraine Oct 7, 2020
3a41dd1
nits
adamraine Oct 9, 2020
d207b8c
sort
adamraine Oct 9, 2020
d8a793f
comments
adamraine Nov 11, 2020
7d5d2b7
more comment
adamraine Nov 11, 2020
87b15d0
rename rowOther
adamraine Nov 11, 2020
02210e7
rename rowOther pt2
adamraine Nov 11, 2020
86690f0
update condense function
adamraine Nov 11, 2020
b90640a
join the dark side
adamraine Nov 11, 2020
9a534e3
rn other resources
adamraine Nov 11, 2020
11d2d65
update translator comment
adamraine Nov 11, 2020
f97895b
more translator comment updates
adamraine Nov 11, 2020
cb27904
update comments
adamraine Nov 11, 2020
b67a145
update html
adamraine Nov 11, 2020
1776f1e
update smoke expectations
adamraine Nov 11, 2020
1539de8
update sample
adamraine Nov 11, 2020
2256b7c
Merge branch 'master' into lazy-third-party
adamraine Nov 11, 2020
d617f06
Update lighthouse-core/audits/third-party-facades.js
adamraine Nov 11, 2020
2d7158e
Update learn more link
adamraine Dec 1, 2020
bb4f9be
Merge branch 'master' into lazy-third-party
adamraine Dec 2, 2020
482dd42
update sample
adamraine Dec 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lighthouse-cli/test/cli/__snapshots__/index-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ Object {
Object {
"path": "third-party-summary",
},
Object {
"path": "third-party-facades",
},
Object {
"path": "largest-contentful-paint-element",
},
Expand Down Expand Up @@ -998,6 +1001,11 @@ Object {
"id": "third-party-summary",
"weight": 0,
},
Object {
"group": "diagnostics",
"id": "third-party-facades",
"weight": 0,
},
Object {
"group": "diagnostics",
"id": "largest-contentful-paint-element",
Expand Down
14 changes: 14 additions & 0 deletions lighthouse-cli/test/fixtures/perf/third-party.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
* 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.
-->
<!DOCTYPE html>
<html>
<body>

<div>AAAAAAAAAAAAAAAAAAA</div>
adamraine marked this conversation as resolved.
Show resolved Hide resolved
<iframe width="420" height="315" src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>

</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -354,4 +354,31 @@ module.exports = [
},
},
},
{
lhr: {
adamraine marked this conversation as resolved.
Show resolved Hide resolved
requestedUrl: 'http://localhost:10200/perf/third-party.html',
finalUrl: 'http://localhost:10200/perf/third-party.html',
audits: {
'third-party-facades': {
score: 0,
displayValue: '1 facade alternative available',
details: {
items: [
{
product: 'YouTube Embedded Player (Video)',
blockingTime: 0,
transferSize: '651128 +/- 100000',
subItems: {
type: 'subitems',
items: {
length: 8,
adamraine marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
],
},
},
},
},
},
];
209 changes: 209 additions & 0 deletions lighthouse-core/audits/third-party-facades.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/**
* @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';

/**
* @fileoverview Audit which identifies third-party code on the page which can be lazy loaded.
* The audit will recommend a facade alternative which is used to imitate the third party resource until it is needed.
*
* Entity: Set of domains which are used by a company or product area to deliver third party resources
adamraine marked this conversation as resolved.
Show resolved Hide resolved
* Product: Specific piece of software belonging to an entity. Entities can have multiple products.
* Facade: Placeholder for a product which looks likes the actual product and replaces itself with that product when the user needs it.
*/

/** @typedef {import("third-party-web").IEntity} ThirdPartyEntity */
/** @typedef {import("third-party-web").IProduct} ThirdPartyProduct*/
/** @typedef {import("third-party-web").IFacade} ThirdPartyFacade*/

/** @typedef {{product: ThirdPartyProduct, entity: ThirdPartyEntity}} FacadableProduct */

const Audit = require('./audit.js');
const i18n = require('../lib/i18n/i18n.js');
const thirdPartyWeb = require('../lib/third-party-web.js');
const NetworkRecords = require('../computed/network-records.js');
const MainResource = require('../computed/main-resource.js');
const MainThreadTasks = require('../computed/main-thread-tasks.js');
const ThirdPartySummary = require('./third-party-summary.js');

const UIStrings = {
/** Title of a diagnostic audit that provides details about the third-party code on a web page that can be lazy loaded with a facade alternative. This descriptive title is shown to users when no resources have facade alternatives available. Lazy loading means loading resources is deferred until they are needed. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "third party" will need to be explained in the translation comment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** Title of a diagnostic audit that provides details about the third-party code on a web page that can be lazy loaded with a facade alternative. This descriptive title is shown to users when no resources have facade alternatives available. Lazy loading means loading resources is deferred until they are needed. */
/** Title of a diagnostic audit that provides details about the third-party code on a web page that can be lazy loaded with a facade alternative. This descriptive title is shown to users when no resources have facade alternatives available. Lazy loading means loading resources is deferred until they are needed. Third-party code refers to resources that are not within the control of the site owner. */

maybe? I would have an inclination to shorten the lazy explanation to just "Lazy loading means resources are deferred until they are needed` but not sure if you specifically wanted to capture the idea that the request is deferred (I'm not sure that nuance will come across to our translators though 🤷)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these probably also need a "facade" explanation

Copy link
Collaborator

@connorjclark connorjclark Nov 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

starting to wonder if we should add a glossary to our i18n support

/**
 * @glossary
 * @word {Facade} Something blah blah blah
 * @word {Product} Something blah blah blah
 * @word {Third-Party} Something blah blah blah
 */

And then concat all of these definitions to every translator comment in this file when we collect strings.

title: 'Lazy load third-party resources with facades',
/** Title of a diagnostic audit that provides details about the third-party code on a web page that can be lazy loaded with a facade alternative. This descriptive title is shown to users when one or more third-party resources have available facade alternatives. Lazy loading means loading resources is deferred until they are needed. */
adamraine marked this conversation as resolved.
Show resolved Hide resolved
failureTitle: 'Some third-party resources can be lazy loaded with a facade',
/** Description of a Lighthouse audit that identifies the third party code on the page that can be lazy loaded with a facade alternative. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. Lazy loading means loading resources is deferred until they are needed. */
adamraine marked this conversation as resolved.
Show resolved Hide resolved
description: 'Some third party embeds can be lazy loaded. ' +
adamraine marked this conversation as resolved.
Show resolved Hide resolved
'Consider replacing them with a facade until they are required. [Learn more](https://web.dev/efficiently-load-third-party-javascript/).',
adamraine marked this conversation as resolved.
Show resolved Hide resolved
/** Summary text for the result of a Lighthouse audit that identifies the third party code on a web page that can be lazy loaded with a facade alternative. This text summarizes the number of lazy loading facades that can be used on the page. Lazy loading means loading resources is deferred until they are needed. */
adamraine marked this conversation as resolved.
Show resolved Hide resolved
displayValue: `{itemCount, plural,
=1 {# facade alternative available}
other {# facade alternatives available}
}`,
/** Label for a table column that displays the name of the product that a URL is used for. A product is a piece of software used on the page. */
adamraine marked this conversation as resolved.
Show resolved Hide resolved
columnProduct: 'Product',
/**
* @description Template for a table entry that gives the name of a product which we categorize as video related.
* @example {YouTube Embedded Player} productName
*/
categoryVideo: '{productName} (Video)',
/**
* @description Template for a table entry that gives the name of a product which we categorize as customer success related. Customer success means the product supports customers by offering chat and contact solutions.
* @example {Intercom Widget} productName
*/
categoryCustomerSuccess: '{productName} (Customer Success)',
/**
* @description Template for a table entry that gives the name of a product which we categorize as marketing related.
* @example {Drift Live Chat} productName
*/
categoryMarketing: '{productName} (Marketing)',
/**
* @description Template for a table entry that gives the name of a product which we categorize as social related.
* @example {Facebook Messenger Customer Chat} productName
*/
categorySocial: '{productName} (Social)',
};

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

/** @type {Record<string, string>} */
adamraine marked this conversation as resolved.
Show resolved Hide resolved
const CATEGORY_UI_MAP = {
'video': UIStrings.categoryVideo,
'customer-success': UIStrings.categoryCustomerSuccess,
'marketing': UIStrings.categoryMarketing,
'social': UIStrings.categorySocial,
};

class ThirdPartyFacades extends Audit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'third-party-facades',
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['traces', 'devtoolsLogs', 'URL'],
};
}

/**
* @param {ThirdPartySummary.URLSummary[]} items
adamraine marked this conversation as resolved.
Show resolved Hide resolved
*/
static condenseItems(items) {
adamraine marked this conversation as resolved.
Show resolved Hide resolved
items.sort((a, b) => b.transferSize - a.transferSize);
const splitIndex = items.findIndex((item) => item.transferSize < 1000);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like we could roll up a little more, this index or a max of 6 or something similar to the other third party audit?

if (splitIndex === -1) return;

const remainder = items.splice(splitIndex);
const finalItem = remainder.reduce((result, item) => {
adamraine marked this conversation as resolved.
Show resolved Hide resolved
result.transferSize += item.transferSize;
result.blockingTime += item.blockingTime;
return result;
});
finalItem.url = str_(i18n.UIStrings.otherValue);
items.push(finalItem);
}

/**
* @param {Map<string, ThirdPartySummary.Summary>} byURL
* @param {ThirdPartyEntity | undefined} mainEntity
* @return {FacadableProduct[]}
*/
static getProductsWithFacade(byURL, mainEntity) {
/** @type {Map<string, FacadableProduct>} */
const facadableProductMap = new Map();
for (const url of byURL.keys()) {
const entity = thirdPartyWeb.getEntity(url);
if (!entity || thirdPartyWeb.isFirstParty(url, mainEntity)) continue;

const product = thirdPartyWeb.getProduct(url);
if (!product || !product.facades || !product.facades.length) continue;

if (facadableProductMap.has(product.name)) continue;
facadableProductMap.set(product.name, {product, entity});
}

return Array.from(facadableProductMap.values());
}

/**
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const settings = context.settings;
const trace = artifacts.traces[Audit.DEFAULT_PASS];
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
const mainResource = await MainResource.request({devtoolsLog, URL: artifacts.URL}, context);
const mainEntity = thirdPartyWeb.getEntity(mainResource.url);
const tasks = await MainThreadTasks.request(trace, context);
const multiplier = settings.throttlingMethod === 'simulate' ?
settings.throttling.cpuSlowdownMultiplier : 1;
const summaries = ThirdPartySummary.getSummaries(networkRecords, tasks, multiplier);
const facadableProducts =
ThirdPartyFacades.getProductsWithFacade(summaries.byURL, mainEntity);

/** @type {LH.Audit.Details.TableItem[]} */
const results = [];
for (const {product, entity} of facadableProducts) {
const categoryTemplate = CATEGORY_UI_MAP[product.categories[0]];

let productWithCategory;
if (categoryTemplate) {
// Display product name with category next to it in the same column
productWithCategory = str_(categoryTemplate, {productName: product.name});
} else {
// Just display product name if no category is found
productWithCategory = product.name;
brendankenny marked this conversation as resolved.
Show resolved Hide resolved
}

const urls = summaries.urls.get(entity);
const entitySummary = summaries.byEntity.get(entity);
if (!urls || !entitySummary) continue;

const items = Array.from(urls).map((url) => {
const urlStats = summaries.byURL.get(url);
return /** @type {ThirdPartySummary.URLSummary} */ ({url, ...urlStats});
});
this.condenseItems(items);
results.push({
product: productWithCategory,
transferSize: entitySummary.transferSize,
blockingTime: entitySummary.blockingTime,
subItems: {type: 'subitems', items},
});
}

if (!results.length) {
return {
score: 1,
notApplicable: true,
};
}

/** @type {LH.Audit.Details.Table['headings']} */
const headings = [
/* eslint-disable max-len */
{key: 'product', itemType: 'text', subItemsHeading: {key: 'url', itemType: 'url'}, text: str_(UIStrings.columnProduct)},
{key: 'transferSize', itemType: 'bytes', subItemsHeading: {key: 'transferSize'}, granularity: 1, text: str_(i18n.UIStrings.columnTransferSize)},
{key: 'blockingTime', itemType: 'ms', subItemsHeading: {key: 'blockingTime'}, granularity: 1, text: str_(i18n.UIStrings.columnBlockingTime)},
/* eslint-enable max-len */
];

return {
score: 0,
displayValue: str_(UIStrings.displayValue, {
itemCount: results.length,
}),
details: Audit.makeTableDetails(headings, results),
};
}
}

module.exports = ThirdPartyFacades;
module.exports.UIStrings = UIStrings;
35 changes: 17 additions & 18 deletions lighthouse-core/audits/third-party-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,9 @@ const UIStrings = {
'your page has primarily finished loading. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/).',
/** Label for a table column that displays the name of a third-party provider that potentially links to their website. */
columnThirdParty: 'Third-Party',
/** Label for a table column that displays how much time each row spent blocking other work on the main thread, entries will be the number of milliseconds spent. */
columnBlockingTime: 'Main-Thread Blocking Time',
/** Summary text for the result of a Lighthouse audit that identifies the code on a web page that the user doesn't control (referred to as "third-party code"). This text summarizes the number of distinct entities that were found on the page. */
displayValue: 'Third-party code blocked the main thread for ' +
`{timeInMs, number, milliseconds}\xa0ms`,
/** Label used to identify a value in a table where many individual values are aggregated to a single value, for brevity. "Other resources" could also be read as "the rest of the resources". Resource refers to network resources requested by the browser. */
otherValue: 'Other resources',
};

const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);
Expand All @@ -41,21 +37,24 @@ const PASS_THRESHOLD_IN_MS = 250;
/** @typedef {import("third-party-web").IEntity} ThirdPartyEntity */

/**
* @typedef {{
* mainThreadTime: number,
* transferSize: number,
* blockingTime: number,
* }} Summary
* @typedef Summary
* @property {number} mainThreadTime
* @property {number} transferSize
* @property {number} blockingTime
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of style changes in this file with no accompanying functional changes anymore. Is it worth keeping the style changes anyway?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes are good, lets keep

*/

/**
* @typedef {{
* transferSize: number,
* blockingTime: number,
* url: string | LH.IcuMessage,
* }} URLSummary
* @typedef URLSummary
* @property {number} transferSize
* @property {number} blockingTime
* @property {string | LH.IcuMessage} url
*/

/** @typedef SummaryMaps
* @property {Map<ThirdPartyEntity, Summary>} byEntity Map of impact summaries for each entity.
* @property {Map<string, Summary>} byURL Map of impact summaries for each URL.
* @property {Map<ThirdPartyEntity, string[]>} urls Map of URLs under each entity.
*/

/**
* Don't bother showing resources smaller than 4KiB since they're likely to be pixels, which isn't
Expand Down Expand Up @@ -85,7 +84,7 @@ class ThirdPartySummary extends Audit {
* @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
* @param {Array<LH.Artifacts.TaskNode>} mainThreadTasks
* @param {number} cpuMultiplier
* @return {{byEntity: Map<ThirdPartyEntity, Summary>, byURL: Map<string, Summary>, urls: Map<ThirdPartyEntity, string[]>}}
* @return {SummaryMaps}
*/
static getSummaries(networkRecords, mainThreadTasks, cpuMultiplier) {
/** @type {Map<string, Summary>} */
Expand Down Expand Up @@ -142,7 +141,7 @@ class ThirdPartySummary extends Audit {

/**
* @param {ThirdPartyEntity} entity
* @param {{byEntity: Map<ThirdPartyEntity, Summary>, byURL: Map<string, Summary>, urls: Map<ThirdPartyEntity, string[]>}} summaries
* @param {SummaryMaps} summaries
* @param {Summary} stats
* @return {Array<URLSummary>}
*/
Expand Down Expand Up @@ -179,7 +178,7 @@ class ThirdPartySummary extends Audit {
// we'll replace the tail entries with single remainder entry.
items = items.slice(0, numSubItems);
const remainder = {
url: str_(UIStrings.otherValue),
url: str_(i18n.UIStrings.otherValue),
transferSize: stats.transferSize - subitemSummary.transferSize,
blockingTime: stats.blockingTime - subitemSummary.blockingTime,
};
Expand Down Expand Up @@ -237,7 +236,7 @@ class ThirdPartySummary extends Audit {
/* eslint-disable max-len */
{key: 'entity', itemType: 'link', text: str_(UIStrings.columnThirdParty), subItemsHeading: {key: 'url', itemType: 'url'}},
{key: 'transferSize', granularity: 1, itemType: 'bytes', text: str_(i18n.UIStrings.columnTransferSize), subItemsHeading: {key: 'transferSize'}},
{key: 'blockingTime', granularity: 1, itemType: 'ms', text: str_(UIStrings.columnBlockingTime), subItemsHeading: {key: 'blockingTime'}},
{key: 'blockingTime', granularity: 1, itemType: 'ms', text: str_(i18n.UIStrings.columnBlockingTime), subItemsHeading: {key: 'blockingTime'}},
/* eslint-enable max-len */
];

Expand Down
2 changes: 2 additions & 0 deletions lighthouse-core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ const defaultConfig = {
'timing-budget',
'resource-summary',
'third-party-summary',
'third-party-facades',
'largest-contentful-paint-element',
'layout-shift-elements',
'long-tasks',
Expand Down Expand Up @@ -467,6 +468,7 @@ const defaultConfig = {
{id: 'timing-budget', weight: 0, group: 'budgets'},
{id: 'resource-summary', weight: 0, group: 'diagnostics'},
{id: 'third-party-summary', weight: 0, group: 'diagnostics'},
{id: 'third-party-facades', weight: 0, group: 'diagnostics'},
{id: 'largest-contentful-paint-element', weight: 0, group: 'diagnostics'},
{id: 'layout-shift-elements', weight: 0, group: 'diagnostics'},
{id: 'uses-passive-event-listeners', weight: 0, group: 'diagnostics'},
Expand Down
4 changes: 4 additions & 0 deletions lighthouse-core/lib/i18n/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ const UIStrings = {
columnWastedBytes: 'Potential Savings',
/** Label for a column in a data table; entries will be the number of milliseconds the user could reduce page load by if they implemented the suggestions. */
columnWastedMs: 'Potential Savings',
/** Label for a table column that displays how much time each row spent blocking other work on the main thread, entries will be the number of milliseconds spent. */
columnBlockingTime: 'Main-Thread Blocking Time',
/** Label for a column in a data table; entries will be the number of milliseconds spent during a particular activity. */
columnTimeSpent: 'Time Spent',
/** Label for a column in a data table; entries will be the location of a specific line of code in a file, in the format "line: 102". */
Expand Down Expand Up @@ -108,6 +110,8 @@ const UIStrings = {
otherResourceType: 'Other',
/** Label for a row in a data table; entries will be the total number and byte size of all third-party resources loaded by a web page. 'Third-party resources are items loaded from URLs that aren't controlled by the owner of the web page. */
thirdPartyResourceType: 'Third-party',
/** Label used to identify a value in a table where many individual values are aggregated to a single value, for brevity. "Other resources" could also be read as "the rest of the resources". Resource refers to network resources requested by the browser. */
otherValue: 'Other resources',
adamraine marked this conversation as resolved.
Show resolved Hide resolved
/** The name of the metric that marks the time at which the first text or image is painted by the browser. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */
firstContentfulPaintMetric: 'First Contentful Paint',
/** The name of the metric that marks when the page has displayed content and the CPU is not busy executing the page's scripts. Shown to users as the label for the numeric metric value. Ideally fits within a ~40 character limit. */
Expand Down
Loading