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: entity-classification #14614

Closed
wants to merge 75 commits into from
Closed
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
7833354
First cut of entity classification computed artifact.
alexnj Oct 20, 2022
0a154eb
some cleanup on the types
alexnj Oct 20, 2022
3212aa6
Refactor resource-summary audit with third party classification
alexnj Oct 20, 2022
c71a8ab
Refactor unused-javascript to output entity and is-3p flag
alexnj Oct 21, 2022
14163bd
Refactor 3p audits to depend on computed entity classification.
alexnj Nov 1, 2022
46d706c
Expose entity classification to LH report via a hidden audit.
alexnj Nov 1, 2022
b5caa4f
Refine groupBy feature to be more concise.
alexnj Nov 1, 2022
8689903
Replace domains with homepage
alexnj Nov 8, 2022
5b67f2e
Revert the LHR grouping changes, after discussing the design with team.
alexnj Nov 8, 2022
0abc053
Add name based lookup to entity classification audit result.
alexnj Nov 11, 2022
170adcb
Refactor third-party filter to base on entity-classification
alexnj Nov 14, 2022
5e18f75
Attach entity classification to ByteEfficiencyAudit.
alexnj Nov 14, 2022
f0674c7
Classify bootup-time (Reduce JavaScript execution time) audit
alexnj Nov 14, 2022
69725b7
Classify long-tasks (Avoid long main-thread tasks) audit
alexnj Nov 14, 2022
ab5d847
Classify uses-long-cache-ttl audit.
alexnj Nov 15, 2022
04bfff8
Mark sub-items with entity as well
alexnj Nov 15, 2022
e8c1c7e
Fix the regression caused to third-party-summary audit
alexnj Nov 15, 2022
0a87d78
Classify uses-rel-preconnect audit.
alexnj Nov 15, 2022
d953829
Classify all ViolationAudit derived audits.
alexnj Nov 15, 2022
aea71bf
Classify no-unload-listeners audit
alexnj Nov 15, 2022
cb16f02
Classify total-byte-weight audit
alexnj Nov 15, 2022
1e73c13
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Nov 16, 2022
e79f44b
Updated components/CSS
alexnj Nov 16, 2022
6f80513
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Nov 16, 2022
d299ae8
Some cleanup
alexnj Nov 16, 2022
f462dc8
Classify valid-source-maps audit
alexnj Nov 16, 2022
9189494
Classify legacy-javascript audit
alexnj Nov 16, 2022
f1d9893
Classify all audits that depend on makeOpportunityDetails call
alexnj Nov 17, 2022
1ad67ac
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Dec 5, 2022
0230896
Explicitly name the lookup tables.
alexnj Dec 8, 2022
abf81f9
Update types on entity classification
alexnj Dec 9, 2022
73cc72d
Update unit tests of ViolationAudit based tests.
alexnj Dec 9, 2022
1daccab
Unit tests: Legacy Javascript and Bootup Time.
alexnj Dec 9, 2022
8cd7347
Fix the bug introduced into firstPartyHostname calculation.
alexnj Dec 9, 2022
4a44dc6
Bugfix: Rely on Artifacts.URL.mainDocumentUrl for 1P calc.
alexnj Dec 9, 2022
60c609a
Classify and update unit tests of 3P facades audit.
alexnj Dec 9, 2022
39753fe
Unit tests for 3p facades test.
alexnj Dec 9, 2022
0459e38
First party detection should fall back to finalDisplayedUrl.
alexnj Dec 10, 2022
a9e5d6a
Update third-party-summary tests.
alexnj Dec 12, 2022
f7adfe3
Allow audits to override entity on items.
alexnj Dec 13, 2022
21a53ba
update tests for valid-source-maps
alexnj Dec 13, 2022
da02b4f
Update snapshots + flow
alexnj Dec 13, 2022
8780384
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Dec 13, 2022
880c09e
Make third-party filtering backward compatible to old LHRs.
alexnj Dec 13, 2022
86fc747
Remove extra space
alexnj Dec 13, 2022
122486e
Unit tests for Audit.makeOpportunityDetails
alexnj Dec 13, 2022
d14d703
Updated tests cases set.
alexnj Dec 14, 2022
ac3f59e
Updated tests set.
alexnj Dec 14, 2022
d373c45
Remove redundant entity marker.
alexnj Dec 14, 2022
171d563
some minor fixups.
alexnj Dec 14, 2022
1059e6a
Entity classification unit tests.
alexnj Dec 15, 2022
ad43021
Computed entity-classification artifact unit tests.
alexnj Dec 15, 2022
02f212a
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Dec 15, 2022
99a9a67
Fix navigation and timespan E2E audit counts.
alexnj Dec 15, 2022
793b1ae
Explicitly handle entity-classification details.type
alexnj Dec 15, 2022
6eef166
Shorter explanation for tsc-expect-error
alexnj Dec 15, 2022
2667564
apparently i cant see squiggly lines
alexnj Dec 15, 2022
36bff06
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Dec 15, 2022
2f50be6
Review fixes
alexnj Dec 16, 2022
093d60c
Refactor entity-classification to shed LUT/lookup tables.
alexnj Dec 16, 2022
9e29828
Merge remote-tracking branch 'origin/main' into entity-based-3p
alexnj Dec 16, 2022
ba515ab
Review changes: Filter network URLs without a valid domain out.
alexnj Dec 17, 2022
85c0cbf
Review changes: details-renderer changes
alexnj Dec 17, 2022
e615e0e
Review changes: Missed an init change in details-renderer
alexnj Dec 17, 2022
75531b7
Review changes: Some more
alexnj Dec 17, 2022
e9f0a0d
Remove getOrigin from report-util as it's no longer needed.
alexnj Dec 17, 2022
7f96df8
Review changes: name and semantics changes on entity-classification.
alexnj Dec 20, 2022
6089f43
Remove the unused getOrigin fn.
alexnj Dec 20, 2022
7cabc7a
Review changes: Convenience functions.
alexnj Dec 20, 2022
3197197
Review changes: formatting.
alexnj Jan 1, 2023
97bfc2e
Review changes: syntax fixes
alexnj Jan 5, 2023
66ec08e
Review changes: Assume artifacts.URL is present
alexnj Jan 6, 2023
589b909
Review changes: @returns to @return
alexnj Jan 6, 2023
261843b
Review changes: Exclude entity-classification from categories.
alexnj Jan 6, 2023
dbec879
Merge branch 'main' into entity-based-3p
alexnj Jan 6, 2023
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
10 changes: 8 additions & 2 deletions core/audits/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,23 @@ class Audit {
/**
alexnj marked this conversation as resolved.
Show resolved Hide resolved
* @param {LH.Audit.Details.Opportunity['headings']} headings
* @param {LH.Audit.Details.Opportunity['items']} items
* @param {LH.Artifacts.EntityClassification|null} classifiedEntities
* @param {number} overallSavingsMs
* @param {number=} overallSavingsBytes
* @return {LH.Audit.Details.Opportunity}
*/
static makeOpportunityDetails(headings, items, overallSavingsMs, overallSavingsBytes) {
static makeOpportunityDetails(headings, items, classifiedEntities,
overallSavingsMs, overallSavingsBytes) {
Audit.assertHeadingKeysExist(headings, items);

return {
type: 'opportunity',
headings: items.length === 0 ? [] : headings,
items,
items: items.map(
// We let an existing item.entity take precedence if it was set during
// the audit (eg., uses-rel-preconnect).
item => ({entity: classifiedEntities?.getEntityName(item.url), ...item})
),
overallSavingsMs,
overallSavingsBytes,
};
Expand Down
6 changes: 5 additions & 1 deletion core/audits/bootup-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import {Audit} from './audit.js';
import {EntityClassification} from '../computed/entity-classification.js';
import {taskGroups} from '../lib/tracehouse/task-groups.js';
import * as i18n from '../lib/i18n/i18n.js';
import {NetworkRecords} from '../computed/network-records.js';
Expand Down Expand Up @@ -44,7 +45,7 @@ class BootupTime extends Audit {
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
requiredArtifacts: ['traces', 'devtoolsLogs'],
requiredArtifacts: ['traces', 'devtoolsLogs', 'URL'],
};
}

Expand Down Expand Up @@ -72,6 +73,8 @@ class BootupTime extends Audit {
const devtoolsLog = artifacts.devtoolsLogs[BootupTime.DEFAULT_PASS];
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
const tasks = await MainThreadTasks.request(trace, context);
const classifiedEntities = await EntityClassification.request(
{URL: artifacts.URL, devtoolsLog}, context);
const multiplier = settings.throttlingMethod === 'simulate' ?
settings.throttling.cpuSlowdownMultiplier : 1;

Expand Down Expand Up @@ -105,6 +108,7 @@ class BootupTime extends Audit {
// Highlight the JavaScript task costs
scripting: scriptingTotal,
scriptParseCompile: parseCompileTotal,
entity: classifiedEntities?.getEntityName(url),
};
})
.filter(result => result.total >= context.options.thresholdInMs)
Expand Down
11 changes: 7 additions & 4 deletions core/audits/byte-efficiency/byte-efficiency-audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import {Audit} from '../audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import {linearInterpolation} from '../../lib/statistics.js';
import {LanternInteractive} from '../../computed/metrics/lantern-interactive.js';
import * as i18n from '../../lib/i18n/i18n.js';
Expand Down Expand Up @@ -116,6 +117,7 @@ class ByteEfficiencyAudit extends Audit {
};
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
const hasContentfulRecords = networkRecords.some(record => record.transferSize);
const classifiedEntities = await EntityClassification.request({URL, devtoolsLog}, context);

// Requesting load simulator requires non-empty network records.
// Timespans are not guaranteed to have any network activity.
Expand All @@ -136,7 +138,7 @@ class ByteEfficiencyAudit extends Audit {
LoadSimulator.request(simulatorOptions, context),
]);

return this.createAuditProduct(result, graph, simulator, gatherContext);
return this.createAuditProduct(result, graph, simulator, gatherContext, classifiedEntities);
}

/**
Expand Down Expand Up @@ -206,11 +208,11 @@ class ByteEfficiencyAudit extends Audit {
* @param {Node|null} graph
* @param {Simulator} simulator
* @param {LH.Artifacts['GatherContext']} gatherContext
* @param {LH.Artifacts.EntityClassification} classifiedEntities
* @return {LH.Audit.Product}
*/
static createAuditProduct(result, graph, simulator, gatherContext) {
static createAuditProduct(result, graph, simulator, gatherContext, classifiedEntities) {
const results = result.items.sort((itemA, itemB) => itemB.wastedBytes - itemA.wastedBytes);

const wastedBytes = results.reduce((sum, item) => sum + item.wastedBytes, 0);

let wastedMs;
Expand All @@ -228,7 +230,8 @@ class ByteEfficiencyAudit extends Audit {
displayValue = str_(i18n.UIStrings.displayValueByteSavings, {wastedBytes});
}

const details = Audit.makeOpportunityDetails(result.headings, results, wastedMs, wastedBytes);
const details = Audit.makeOpportunityDetails(result.headings, results,
classifiedEntities, wastedMs, wastedBytes);

return {
explanation: result.explanation,
Expand Down
11 changes: 8 additions & 3 deletions core/audits/byte-efficiency/legacy-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@

import fs from 'fs';

import {Audit} from '../audit.js';
import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import {JSBundles} from '../../computed/js-bundles.js';
import * as i18n from '../../lib/i18n/i18n.js';
import thirdPartyWeb from '../../lib/third-party-web.js';
import {getRequestForScript} from '../../lib/script-helpers.js';
import {LH_ROOT} from '../../../root.js';

Expand Down Expand Up @@ -401,7 +402,10 @@ class LegacyJavascript extends ByteEfficiencyAudit {
* @return {Promise<ByteEfficiencyProduct>}
*/
static async audit_(artifacts, networkRecords, context) {
const mainDocumentEntity = thirdPartyWeb.getEntity(artifacts.URL.finalDisplayedUrl);
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const classifiedEntities = await EntityClassification.request(
{URL: artifacts.URL, devtoolsLog}, context);

const bundles = await JSBundles.request(artifacts, context);

/** @type {Item[]} */
Expand Down Expand Up @@ -431,6 +435,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
},
// Not needed, but keeps typescript happy.
totalBytes: 0,
entity: classifiedEntities.getEntityName(script.url),
};

const bundle = bundles.find(bundle => bundle.script.scriptId === script.scriptId);
Expand All @@ -450,7 +455,7 @@ class LegacyJavascript extends ByteEfficiencyAudit {
const wastedBytesByUrl = new Map();
for (const item of items) {
// Only estimate savings if first party code has legacy code.
if (thirdPartyWeb.isFirstParty(item.url, mainDocumentEntity)) {
if (classifiedEntities.isFirstParty(item.url)) {
wastedBytesByUrl.set(item.url, item.wastedBytes);
}
}
Expand Down
6 changes: 5 additions & 1 deletion core/audits/byte-efficiency/render-blocking-resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {Audit} from '../audit.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {BaseNode} from '../../lib/dependency-graph/base-node.js';
import {ByteEfficiencyAudit} from './byte-efficiency-audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import {UnusedCSS} from '../../computed/unused-css.js';
import {NetworkRequest} from '../../lib/network-request.js';
import {ProcessedTrace} from '../../computed/processed-trace.js';
Expand Down Expand Up @@ -278,6 +279,9 @@ class RenderBlockingResources extends Audit {
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const URL = artifacts.URL;
const classifiedEntities = await EntityClassification.request({URL, devtoolsLog}, context);
const {results, wastedMs} = await RenderBlockingResources.computeResults(artifacts, context);

let displayValue;
Expand All @@ -292,7 +296,7 @@ class RenderBlockingResources extends Audit {
{key: 'wastedMs', valueType: 'timespanMs', label: str_(i18n.UIStrings.columnWastedMs)},
];

const details = Audit.makeOpportunityDetails(headings, results, wastedMs);
const details = Audit.makeOpportunityDetails(headings, results, classifiedEntities, wastedMs);

return {
displayValue,
Expand Down
6 changes: 5 additions & 1 deletion core/audits/byte-efficiency/total-byte-weight.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import {Audit} from '../audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import * as i18n from '../../lib/i18n/i18n.js';
import {NetworkRequest} from '../../lib/network-request.js';
import {NetworkRecords} from '../../computed/network-records.js';
Expand Down Expand Up @@ -35,7 +36,7 @@ class TotalByteWeight extends Audit {
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
requiredArtifacts: ['devtoolsLogs'],
requiredArtifacts: ['devtoolsLogs', 'URL'],
};
}

Expand All @@ -60,6 +61,8 @@ class TotalByteWeight extends Audit {
static async audit(artifacts, context) {
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const records = await NetworkRecords.request(devtoolsLog, context);
const classifiedEntities = await EntityClassification.request(
{URL: artifacts.URL, devtoolsLog}, context);

let totalBytes = 0;
/** @type {Array<{url: string, totalBytes: number}>} */
Expand All @@ -72,6 +75,7 @@ class TotalByteWeight extends Audit {
const result = {
url: record.url,
totalBytes: record.transferSize,
entity: classifiedEntities.getEntityName(record.url),
};

totalBytes += result.totalBytes;
Expand Down
10 changes: 7 additions & 3 deletions core/audits/byte-efficiency/uses-long-cache-ttl.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import parseCacheControl from 'parse-cache-control';

import {Audit} from '../audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import {NetworkRequest} from '../../lib/network-request.js';
import UrlUtils from '../../lib/url-utils.js';
import {linearInterpolation} from '../../lib/statistics.js';
Expand Down Expand Up @@ -45,7 +46,7 @@ class CacheHeaders extends Audit {
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
scoreDisplayMode: Audit.SCORING_MODES.NUMERIC,
requiredArtifacts: ['devtoolsLogs'],
requiredArtifacts: ['devtoolsLogs', 'URL'],
};
}

Expand Down Expand Up @@ -195,8 +196,10 @@ class CacheHeaders extends Audit {
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const devtoolsLogs = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const records = await NetworkRecords.request(devtoolsLogs, context);
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const classifiedEntities = await EntityClassification.request(
{URL: artifacts.URL, devtoolsLog}, context);
const records = await NetworkRecords.request(devtoolsLog, context);
const results = [];
let totalWastedBytes = 0;

Expand Down Expand Up @@ -256,6 +259,7 @@ class CacheHeaders extends Audit {
cacheHitProbability,
totalBytes,
wastedBytes,
entity: classifiedEntities?.getEntityName(url),
});
}

Expand Down
3 changes: 2 additions & 1 deletion core/audits/dobetterweb/geolocation-on-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class GeolocationOnStart extends ViolationAudit {
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
supportedModes: ['navigation'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts',
...ViolationAudit.partialMeta.requiredArtifacts],
};
}

Expand Down
3 changes: 2 additions & 1 deletion core/audits/dobetterweb/no-document-write.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class NoDocWriteAudit extends ViolationAudit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts',
...ViolationAudit.partialMeta.requiredArtifacts],
};
}

Expand Down
3 changes: 2 additions & 1 deletion core/audits/dobetterweb/notification-on-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class NotificationOnStart extends ViolationAudit {
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
supportedModes: ['navigation'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts',
...ViolationAudit.partialMeta.requiredArtifacts],
};
}

Expand Down
12 changes: 10 additions & 2 deletions core/audits/dobetterweb/uses-http2.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/** @typedef {import('../../lib/dependency-graph/base-node.js').Node} Node */

import {Audit} from '../audit.js';
import {EntityClassification} from '../../computed/entity-classification.js';
import ThirdParty from '../../lib/third-party-web.js';
import UrlUtils from '../../lib/url-utils.js';
import {ByteEfficiencyAudit} from '../byte-efficiency/byte-efficiency-audit.js';
Expand Down Expand Up @@ -204,6 +205,7 @@ class UsesHTTP2Audit extends Audit {
const URL = artifacts.URL;
const networkRecords = await NetworkRecords.request(devtoolsLog, context);
const resources = UsesHTTP2Audit.determineNonHttp2Resources(networkRecords);
const classifiedEntities = await EntityClassification.request({URL, devtoolsLog}, context);

let displayValue;
if (resources.length > 0) {
Expand All @@ -218,7 +220,13 @@ class UsesHTTP2Audit extends Audit {
{key: 'protocol', valueType: 'text', label: str_(UIStrings.columnProtocol)},
];

const details = Audit.makeTableDetails(headings, resources);
const details = Audit.makeTableDetails(
headings,
resources.map(resource => ({
entity: classifiedEntities.getEntityName(resource.url),
...resource,
}))
);

return {
displayValue,
Expand All @@ -242,7 +250,7 @@ class UsesHTTP2Audit extends Audit {
{key: 'protocol', valueType: 'text', label: str_(UIStrings.columnProtocol)},
];

const details = Audit.makeOpportunityDetails(headings, resources, wastedMs);
const details = Audit.makeOpportunityDetails(headings, resources, classifiedEntities, wastedMs);

return {
displayValue,
Expand Down
3 changes: 2 additions & 1 deletion core/audits/dobetterweb/uses-passive-event-listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class PassiveEventsAudit extends ViolationAudit {
title: str_(UIStrings.title),
failureTitle: str_(UIStrings.failureTitle),
description: str_(UIStrings.description),
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts'],
requiredArtifacts: ['ConsoleMessages', 'SourceMaps', 'Scripts',
...ViolationAudit.partialMeta.requiredArtifacts],
};
}

Expand Down
62 changes: 62 additions & 0 deletions core/audits/entity-classification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* @license Copyright 2022 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.
*/

import {Audit} from './audit.js';
import {EntityClassification as ComputedEntityClassification}
from '../computed/entity-classification.js';
alexnj marked this conversation as resolved.
Show resolved Hide resolved

class EntityClassification extends Audit {
/**
* @return {LH.Audit.Meta}
*/
static get meta() {
return {
id: 'entity-classification',
scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE,
title: 'Entity Classification',
description: 'All 1st and 3rd party entities on the page classified',
requiredArtifacts: ['devtoolsLogs', 'URL'],
};
}

/**
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
const classifiedEntities = await ComputedEntityClassification.request(
{URL: artifacts.URL, devtoolsLog}, context);

/** @type {Record<string, LH.Audit.Details.EntityClassificationEntity>} */
const entities = {};

for (const entity of classifiedEntities.entityToURLs.keys()) {
/** @type {LH.Audit.Details.EntityClassificationEntity} */
const shortEntity = {
homepage: entity.homepage,
};

// Reduce payload size in LHR JSON by omitting whats falsy.
if (entity === classifiedEntities.firstParty) shortEntity.isFirstParty = true;
if (entity.isUnrecognized) shortEntity.isUnrecognized = true;

entities[entity.name] = shortEntity;
}

return {
score: 1,
details: {
type: 'entity-classification',
entities,
firstParty: classifiedEntities.firstParty?.name,
},
};
}
}

export default EntityClassification;
Loading