Skip to content

core(config): use fr config to construct the legacy config #13965

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

Merged
merged 21 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 4 deletions lighthouse-core/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
'use strict';

import defaultConfig from './default-config.js';
import legacyDefaultConfig from './legacy-default-config.js';
import * as constants from './constants.js';
import format from '../../shared/localization/format.js';
import * as validation from './../fraggle-rock/config/validation.js';
Expand All @@ -24,7 +24,7 @@ import {
} from './config-helpers.js';
import {getModuleDirectory} from '../../esm-utils.js';

const defaultConfigPath = './default-config.js';
const defaultConfigPath = './legacy-default-config.js';

/** @typedef {typeof import('../gather/gatherers/gatherer.js').Gatherer} GathererConstructor */
/** @typedef {InstanceType<GathererConstructor>} Gatherer */
Expand Down Expand Up @@ -168,7 +168,7 @@ class Config {
let configPath = flags?.configPath;

if (!configJSON) {
configJSON = defaultConfig;
configJSON = legacyDefaultConfig;
configPath = path.resolve(getModuleDirectory(import.meta), defaultConfigPath);
}

Expand All @@ -184,7 +184,7 @@ class Config {
if (configJSON.extends !== 'lighthouse:default') {
throw new Error('`lighthouse:default` is the only valid extension method.');
}
configJSON = Config.extendConfigJSON(deepCloneConfigJson(defaultConfig), configJSON);
configJSON = Config.extendConfigJSON(deepCloneConfigJson(legacyDefaultConfig), configJSON);
}

// The directory of the config path, if one was provided.
Expand Down
205 changes: 157 additions & 48 deletions lighthouse-core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,56 +123,160 @@ const UIStrings = {

const str_ = i18n.createMessageInstanceIdFn(import.meta.url, UIStrings);

// Ensure all artifact IDs match the typedefs.
/** @type {Record<keyof LH.FRArtifacts, string>} */
const artifacts = {
DevtoolsLog: '',
Trace: '',
Accessibility: '',
AnchorElements: '',
CacheContents: '',
ConsoleMessages: '',
CSSUsage: '',
Doctype: '',
DOMStats: '',
EmbeddedContent: '',
FontSize: '',
Inputs: '',
FullPageScreenshot: '',
GlobalListeners: '',
IFrameElements: '',
ImageElements: '',
InstallabilityErrors: '',
InspectorIssues: '',
JsUsage: '',
LinkElements: '',
MainDocumentContent: '',
MetaElements: '',
NetworkUserAgent: '',
OptimizedImages: '',
PasswordInputsWithPreventedPaste: '',
ResponseCompression: '',
RobotsTxt: '',
ServiceWorker: '',
ScriptElements: '',
Scripts: '',
SourceMaps: '',
Stacks: '',
TagsBlockingFirstPaint: '',
TapTargets: '',
TraceElements: '',
ViewportDimensions: '',
WebAppManifest: '',
devtoolsLogs: '',
traces: '',
};

for (const key of Object.keys(artifacts)) {
artifacts[/** @type {keyof typeof artifacts} */ (key)] = key;
}

/** @type {LH.Config.Json} */
const defaultConfig = {
settings: constants.defaultSettings,
passes: [{
passName: 'defaultPass',
recordTrace: true,
useThrottling: true,
pauseAfterFcpMs: 1000,
pauseAfterLoadMs: 1000,
networkQuietThresholdMs: 1000,
cpuQuietThresholdMs: 1000,
gatherers: [
'css-usage',
'js-usage',
'viewport-dimensions',
'console-messages',
'anchor-elements',
'image-elements',
'link-elements',
'meta-elements',
'script-elements',
'scripts',
'iframe-elements',
'inputs',
'main-document-content',
'global-listeners',
'dobetterweb/doctype',
'dobetterweb/domstats',
'dobetterweb/optimized-images',
'dobetterweb/password-inputs-with-prevented-paste',
'dobetterweb/response-compression',
'dobetterweb/tags-blocking-first-paint',
'seo/font-size',
'seo/embedded-content',
'seo/robots-txt',
'seo/tap-targets',
'accessibility',
'trace-elements',
'inspector-issues',
'source-maps',
'full-page-screenshot',
],
},
{
passName: 'offlinePass',
loadFailureMode: 'ignore',
gatherers: [
'service-worker',
],
}],
artifacts: [
// Artifacts which can be depended on come first.
{id: artifacts.DevtoolsLog, gatherer: 'devtools-log'},
{id: artifacts.Trace, gatherer: 'trace'},

{id: artifacts.Accessibility, gatherer: 'accessibility'},
{id: artifacts.AnchorElements, gatherer: 'anchor-elements'},
{id: artifacts.CacheContents, gatherer: 'cache-contents'},
{id: artifacts.ConsoleMessages, gatherer: 'console-messages'},
{id: artifacts.CSSUsage, gatherer: 'css-usage'},
{id: artifacts.Doctype, gatherer: 'dobetterweb/doctype'},
{id: artifacts.DOMStats, gatherer: 'dobetterweb/domstats'},
{id: artifacts.EmbeddedContent, gatherer: 'seo/embedded-content'},
{id: artifacts.FontSize, gatherer: 'seo/font-size'},
{id: artifacts.Inputs, gatherer: 'inputs'},
{id: artifacts.GlobalListeners, gatherer: 'global-listeners'},
{id: artifacts.IFrameElements, gatherer: 'iframe-elements'},
{id: artifacts.ImageElements, gatherer: 'image-elements'},
{id: artifacts.InstallabilityErrors, gatherer: 'installability-errors'},
{id: artifacts.InspectorIssues, gatherer: 'inspector-issues'},
{id: artifacts.JsUsage, gatherer: 'js-usage'},
{id: artifacts.LinkElements, gatherer: 'link-elements'},
{id: artifacts.MainDocumentContent, gatherer: 'main-document-content'},
{id: artifacts.MetaElements, gatherer: 'meta-elements'},
{id: artifacts.NetworkUserAgent, gatherer: 'network-user-agent'},
{id: artifacts.OptimizedImages, gatherer: 'dobetterweb/optimized-images'},
{id: artifacts.PasswordInputsWithPreventedPaste, gatherer: 'dobetterweb/password-inputs-with-prevented-paste'},
{id: artifacts.ResponseCompression, gatherer: 'dobetterweb/response-compression'},
{id: artifacts.RobotsTxt, gatherer: 'seo/robots-txt'},
{id: artifacts.ServiceWorker, gatherer: 'service-worker'},
{id: artifacts.ScriptElements, gatherer: 'script-elements'},
{id: artifacts.Scripts, gatherer: 'scripts'},
{id: artifacts.SourceMaps, gatherer: 'source-maps'},
{id: artifacts.Stacks, gatherer: 'stacks'},
{id: artifacts.TagsBlockingFirstPaint, gatherer: 'dobetterweb/tags-blocking-first-paint'},
{id: artifacts.TapTargets, gatherer: 'seo/tap-targets'},
{id: artifacts.TraceElements, gatherer: 'trace-elements'},
{id: artifacts.ViewportDimensions, gatherer: 'viewport-dimensions'},
{id: artifacts.WebAppManifest, gatherer: 'web-app-manifest'},

// Artifact copies are renamed for compatibility with legacy artifacts.
{id: artifacts.devtoolsLogs, gatherer: 'devtools-log-compat'},
{id: artifacts.traces, gatherer: 'trace-compat'},

// FullPageScreenshot comes at the very end so all other node analysis is captured.
{id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
],
navigations: [
{
id: 'default',
pauseAfterFcpMs: 1000,
pauseAfterLoadMs: 1000,
networkQuietThresholdMs: 1000,
cpuQuietThresholdMs: 1000,
artifacts: [
// Artifacts which can be depended on come first.
artifacts.DevtoolsLog,
artifacts.Trace,

artifacts.Accessibility,
artifacts.AnchorElements,
artifacts.CacheContents,
artifacts.ConsoleMessages,
artifacts.CSSUsage,
artifacts.Doctype,
artifacts.DOMStats,
artifacts.EmbeddedContent,
artifacts.FontSize,
artifacts.Inputs,
artifacts.GlobalListeners,
artifacts.IFrameElements,
artifacts.ImageElements,
artifacts.InstallabilityErrors,
artifacts.InspectorIssues,
artifacts.JsUsage,
artifacts.LinkElements,
artifacts.MainDocumentContent,
artifacts.MetaElements,
artifacts.NetworkUserAgent,
artifacts.OptimizedImages,
artifacts.PasswordInputsWithPreventedPaste,
artifacts.ResponseCompression,
artifacts.RobotsTxt,
artifacts.ServiceWorker,
artifacts.ScriptElements,
artifacts.Scripts,
artifacts.SourceMaps,
artifacts.Stacks,
artifacts.TagsBlockingFirstPaint,
artifacts.TapTargets,
artifacts.TraceElements,
artifacts.ViewportDimensions,
artifacts.WebAppManifest,

// Compat artifacts come last.
artifacts.devtoolsLogs,
artifacts.traces,

// FullPageScreenshot comes at the very end so all other node analysis is captured.
artifacts.FullPageScreenshot,
],
},
],
audits: [
'is-on-https',
'service-worker',
Expand All @@ -186,6 +290,7 @@ const defaultConfig = {
'metrics/total-blocking-time',
'metrics/max-potential-fid',
'metrics/cumulative-layout-shift',
'metrics/experimental-interaction-to-next-paint',
'errors-in-console',
'server-response-time',
'metrics/interactive',
Expand Down Expand Up @@ -302,6 +407,7 @@ const defaultConfig = {
'byte-efficiency/efficient-animated-content',
'byte-efficiency/duplicated-javascript',
'byte-efficiency/legacy-javascript',
'byte-efficiency/uses-responsive-images-snapshot',
'dobetterweb/doctype',
'dobetterweb/charset',
'dobetterweb/dom-size',
Expand All @@ -326,8 +432,8 @@ const defaultConfig = {
'seo/plugins',
'seo/canonical',
'seo/manual/structured-data',
'work-during-interaction',
],

groups: {
'metrics': {
title: str_(UIStrings.metricGroupTitle),
Expand Down Expand Up @@ -420,6 +526,7 @@ const defaultConfig = {
{id: 'total-blocking-time', weight: 30, group: 'metrics', acronym: 'TBT', relevantAudits: metricsToAudits.tbtRelevantAudits},
{id: 'largest-contentful-paint', weight: 25, group: 'metrics', acronym: 'LCP', relevantAudits: metricsToAudits.lcpRelevantAudits},
{id: 'cumulative-layout-shift', weight: 15, group: 'metrics', acronym: 'CLS', relevantAudits: metricsToAudits.clsRelevantAudits},
{id: 'experimental-interaction-to-next-paint', weight: 0, group: 'metrics', acronym: 'INP', relevantAudits: metricsToAudits.inpRelevantAudits},

// These are our "invisible" metrics. Not displayed, but still in the LHR.
{id: 'max-potential-fid', weight: 0, group: 'hidden'},
Expand Down Expand Up @@ -466,6 +573,8 @@ const defaultConfig = {
{id: 'unsized-images', weight: 0},
{id: 'viewport', weight: 0},
{id: 'no-unload-listeners', weight: 0},
{id: 'uses-responsive-images-snapshot', weight: 0},
{id: 'work-during-interaction', weight: 0},

// Budget audits.
{id: 'performance-budget', weight: 0, group: 'budgets'},
Expand Down
86 changes: 86 additions & 0 deletions lighthouse-core/config/legacy-default-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* @license Copyright 2018 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 Construct the legacy default config from the standard default config.
*/

import defaultConfig from './default-config.js';

/** @type {LH.Config.Json} */
const legacyDefaultConfig = JSON.parse(JSON.stringify(defaultConfig));
if (!legacyDefaultConfig.categories) {
throw new Error('Default config should always have categories');
}

// These properties are ignored in Legacy navigations.
delete legacyDefaultConfig.artifacts;
delete legacyDefaultConfig.navigations;

// These audits don't work in Legacy navigation mode so we remove them.
const unsupportedAuditIds = [
'experimental-interaction-to-next-paint',
'uses-responsive-images-snapshot',
'work-during-interaction',
];

legacyDefaultConfig.audits = legacyDefaultConfig.audits?.filter(audit =>
!unsupportedAuditIds.find(auditId => audit.toString().endsWith(auditId)));

legacyDefaultConfig.categories['performance'].auditRefs =
legacyDefaultConfig.categories['performance'].auditRefs.filter(auditRef =>
!unsupportedAuditIds.includes(auditRef.id));

legacyDefaultConfig.passes = [{
passName: 'defaultPass',
recordTrace: true,
useThrottling: true,
pauseAfterFcpMs: 1000,
pauseAfterLoadMs: 1000,
networkQuietThresholdMs: 1000,
cpuQuietThresholdMs: 1000,
gatherers: [
'css-usage',
'js-usage',
'viewport-dimensions',
'console-messages',
'anchor-elements',
'image-elements',
'link-elements',
'meta-elements',
'script-elements',
'scripts',
'iframe-elements',
'inputs',
'main-document-content',
'global-listeners',
'dobetterweb/doctype',
'dobetterweb/domstats',
'dobetterweb/optimized-images',
'dobetterweb/password-inputs-with-prevented-paste',
'dobetterweb/response-compression',
'dobetterweb/tags-blocking-first-paint',
'seo/font-size',
'seo/embedded-content',
'seo/robots-txt',
'seo/tap-targets',
'accessibility',
'trace-elements',
'inspector-issues',
'source-maps',
'full-page-screenshot',
],
},
{
passName: 'offlinePass',
loadFailureMode: 'ignore',
gatherers: [
'service-worker',
],
}];

export default legacyDefaultConfig;
7 changes: 5 additions & 2 deletions lighthouse-core/fraggle-rock/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import path from 'path';
import log from 'lighthouse-logger';
import {Runner} from '../../runner.js';
import defaultConfig from './default-config.js';
import defaultConfig from '../../config/default-config.js';
import {defaultNavigationConfig, nonSimulatedPassConfigOverrides} from '../../config/constants.js'; // eslint-disable-line max-len

import {
Expand All @@ -35,7 +35,10 @@ import {
import {getModuleDirectory} from '../../../esm-utils.js';
import * as format from '../../../shared/localization/format.js';

const defaultConfigPath = path.join(getModuleDirectory(import.meta), './default-config.js');
const defaultConfigPath = path.join(
getModuleDirectory(import.meta),
'../../config/default-config.js'
);

/** @typedef {LH.Config.FRContext & {gatherMode: LH.Gatherer.GatherMode}} ConfigContext */

Expand Down
Loading