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

docs: update docs for 10.0 api, configuration #14710

Merged
merged 9 commits into from
Feb 8, 2023
128 changes: 40 additions & 88 deletions core/config/default-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,105 +122,57 @@ const UIStrings = {

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

// Ensure all artifact IDs match the typedefs.
/** @type {Record<keyof LH.FRArtifacts, string>} */
const artifacts = {
DevtoolsLog: '',
Trace: '',
Accessibility: '',
AnchorElements: '',
BFCacheFailures: '',
CacheContents: '',
ConsoleMessages: '',
CSSUsage: '',
Doctype: '',
DOMStats: '',
EmbeddedContent: '',
FontSize: '',
Inputs: '',
FullPageScreenshot: '',
GlobalListeners: '',
IFrameElements: '',
ImageElements: '',
InstallabilityErrors: '',
InspectorIssues: '',
JsUsage: '',
LinkElements: '',
MainDocumentContent: '',
MetaElements: '',
NetworkUserAgent: '',
OptimizedImages: '',
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} */
const defaultConfig = {
settings: constants.defaultSettings,
artifacts: [
// Artifacts which can be depended on come first.
{id: artifacts.DevtoolsLog, gatherer: 'devtools-log'},
{id: artifacts.Trace, gatherer: 'trace'},
{id: 'DevtoolsLog', gatherer: 'devtools-log'},
{id: '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.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'},
{id: 'Accessibility', gatherer: 'accessibility'},
{id: 'AnchorElements', gatherer: 'anchor-elements'},
{id: 'CacheContents', gatherer: 'cache-contents'},
{id: 'ConsoleMessages', gatherer: 'console-messages'},
{id: 'CSSUsage', gatherer: 'css-usage'},
{id: 'Doctype', gatherer: 'dobetterweb/doctype'},
{id: 'DOMStats', gatherer: 'dobetterweb/domstats'},
{id: 'EmbeddedContent', gatherer: 'seo/embedded-content'},
{id: 'FontSize', gatherer: 'seo/font-size'},
{id: 'Inputs', gatherer: 'inputs'},
{id: 'GlobalListeners', gatherer: 'global-listeners'},
{id: 'IFrameElements', gatherer: 'iframe-elements'},
{id: 'ImageElements', gatherer: 'image-elements'},
{id: 'InstallabilityErrors', gatherer: 'installability-errors'},
{id: 'InspectorIssues', gatherer: 'inspector-issues'},
{id: 'JsUsage', gatherer: 'js-usage'},
{id: 'LinkElements', gatherer: 'link-elements'},
{id: 'MainDocumentContent', gatherer: 'main-document-content'},
{id: 'MetaElements', gatherer: 'meta-elements'},
{id: 'NetworkUserAgent', gatherer: 'network-user-agent'},
{id: 'OptimizedImages', gatherer: 'dobetterweb/optimized-images'},
{id: 'ResponseCompression', gatherer: 'dobetterweb/response-compression'},
{id: 'RobotsTxt', gatherer: 'seo/robots-txt'},
{id: 'ServiceWorker', gatherer: 'service-worker'},
{id: 'ScriptElements', gatherer: 'script-elements'},
{id: 'Scripts', gatherer: 'scripts'},
{id: 'SourceMaps', gatherer: 'source-maps'},
{id: 'Stacks', gatherer: 'stacks'},
{id: 'TagsBlockingFirstPaint', gatherer: 'dobetterweb/tags-blocking-first-paint'},
{id: 'TapTargets', gatherer: 'seo/tap-targets'},
{id: 'TraceElements', gatherer: 'trace-elements'},
{id: 'ViewportDimensions', gatherer: 'viewport-dimensions'},
{id: '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'},
{id: 'devtoolsLogs', gatherer: 'devtools-log-compat'},
{id: 'traces', gatherer: 'trace-compat'},

// FullPageScreenshot comes at the end so all other node analysis is captured.
{id: artifacts.FullPageScreenshot, gatherer: 'full-page-screenshot'},
{id: 'FullPageScreenshot', gatherer: 'full-page-screenshot'},

// BFCacheErrors comes at the very end because it can perform a page navigation.
{id: artifacts.BFCacheFailures, gatherer: 'bf-cache-failures'},
// BFCacheFailures comes at the very end because it can perform a page navigation.
{id: 'BFCacheFailures', gatherer: 'bf-cache-failures'},
],
audits: [
'is-on-https',
Expand Down
116 changes: 83 additions & 33 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<!---
TODO(rm-legacy): Remove this when legacy path is gone.
-->
> **WARNING**: This config format is for configs in version 10.0 and beyond. Please read the [legacy config](#legacy-configs) section if you are using the old config format.

# Lighthouse Configuration

The Lighthouse config object is the primary method of customizing Lighthouse to suit your use case. Using a custom config, you can limit the audits to run, add additional loads of the page under special conditions, add your own custom checks, tweak the scoring, and more.
Expand All @@ -10,7 +15,7 @@ You can specify a custom config file when using Lighthouse through the CLI or co

**custom-config.js file**
```js
module.exports = {
export default {
extends: 'lighthouse:default',
settings: {
onlyAudits: [
Expand All @@ -29,9 +34,9 @@ lighthouse --config-path=path/to/custom-config.js https://example.com

**Use config file via Node**
```js
const lighthouse = require('lighthouse');
const config = require('./path/to/custom-config.js');
lighthouse('https://example.com/', {port: 9222}, config);
import lighthouse from 'lighthouse';
import config from './path/to/custom-config.js';
await lighthouse('https://example.com/', {port: 9222}, config);
```

## Properties
Expand Down Expand Up @@ -80,44 +85,23 @@ For full list see [our config settings typedef](https://github.com/GoogleChrome/
| onlyAudits | `string[]` | Includes only the specified audits in the final report. Additive with `onlyCategories` and reduces the time to audit a page. |
| skipAudits | `string[]` | Excludes the specified audits from the final report. Takes priority over `onlyCategories`, not usable in conjuction with `onlyAudits`, and reduces the time to audit a page. |

### `passes: Object[]`

The passes property controls how to load the requested URL and what information to gather about the page while loading. Each entry in the passes array represents one load of the page (e.g. 4 entries in `passes` will load the page 4 times), so be judicious about adding multiple entries here to avoid extending run times.
### `artifacts: Object[]`

Each `passes` entry defines basic settings such as how long to wait for the page to load and whether to record a trace file. Additionally a list of **gatherers** to use is defined per pass. Gatherers can read information from the page to generate artifacts which are later used by audits to provide you with a Lighthouse report. For more information on implementing a custom gatherer and the role they play in building a Lighthouse report, refer to the [recipes](https://github.com/GoogleChrome/lighthouse/blob/main/docs/recipes/custom-audit). Also note that `artifacts.devtoolsLogs` will be automatically populated for every pass. Gatherers also have access to this data within the `afterPass` as `traceData.devtoolsLog` (However, most will find the higher-level `traceData.networkRecords` more useful).
The list of artifacts to collect on a single Lighthouse run. This property is required and on extension will be concatenated with the existing set of artifacts.

For list of default pass values, see [our config constants](https://github.com/GoogleChrome/lighthouse/blob/main/core/config/constants.js).

#### Example
```js
{
passes: [
{
passName: 'fastPass',
gatherers: ['fast-gatherer'],
},
{
passName: 'slowPass',
recordTrace: true,
useThrottling: true,
networkQuietThresholdMs: 5000,
gatherers: ['slow-gatherer'],
}
artifacts: [
{id: 'Accessibility', gatherer: 'accessibility'},
{id: 'AnchorElements', gatherer: 'anchor-elements'},
]
}
```

#### Options
| Name | Type | Description |
| -- | -- | -- |
| passName | `string` | A unique identifier for the pass used in audits and during config extension. |
| recordTrace | `boolean` | Records a [trace](https://github.com/GoogleChrome/lighthouse/blob/main/docs/architecture.md#understanding-a-trace) of the pass when enabled. Available to gatherers during `afterPass` as `traceData.trace` and to audits in `artifacts.traces`. |
| useThrottling | `boolean` | Enables throttling of the pass when enabled. |
| pauseAfterLoadMs | `number` | The number of milliseconds to wait after the load event before the pass can continue. Used to ensure the page has had time for post-load JavaScript to execute before ending a trace. (Default: 0) |
| networkQuietThresholdMs | `number` | The number of milliseconds since the last network request to wait before the page should be considered to have reached 'network quiet'. Used to ensure the page has had time for the full waterfall of network requests to complete before ending a trace. (Default: 5000) |
| pauseAfterNetworkQuietMs | `number` | The number of milliseconds to wait after 'network quiet' before the pass can continue. Used to ensure the page has had time for post-network-quiet JavaScript to execute before ending a trace. (Default: 0) |
| blockedUrlPatterns | `string[]` | URLs of requests to block while loading the page. Basic wildcard support using `*`. |
| gatherers | `string[]` | The list of gatherers to run on this pass. This property is required and on extension will be concatenated with the existing set of gatherers. |
| id | `string` | Unique identifier for this artifact. This is how the artifact is referenced in audits. |
| gatherer | `string` | Gatherer used to produce this artifact. Does not need to be unique within the `artifacts` list. |

### `audits: string[]`

Expand All @@ -133,7 +117,6 @@ The audits property controls which audits to run and include with your Lighthous
}
```


### `categories: Object|undefined`

The categories property controls how to score and organize the audit results in the report. Each category defined in the config will have an entry in the `categories` property of Lighthouse's output. The category output contains the child audit results along with an overall score for the category.
Expand Down Expand Up @@ -162,6 +145,7 @@ The categories property controls how to score and organize the audit results in
| -- | -- | -- |
| title | `string` | The display name of the category. |
| description | `string` | The displayed description of the category. |
| supportedModes | `string[]` (optional, [user flows](https://github.com/GoogleChrome/lighthouse/blob/master/docs/user-flows.md)) | The modes supported by the category. Category will support all modes if this is not provided. |
| auditRefs | `Object[]` | The audits to include in the category. |
| auditRefs[$i].id | `string` | The ID of the audit to include. |
| auditRefs[$i].weight | `number` | The weight of the audit in the scoring of the category. |
Expand Down Expand Up @@ -212,3 +196,69 @@ The best examples are the ones Lighthouse uses itself! There are several referen
* [core/config/perf-config.js](https://github.com/GoogleChrome/lighthouse/blob/main/core/config/perf-config.js)
* [docs/recipes/custom-audit/custom-config.js](https://github.com/GoogleChrome/lighthouse/blob/main/docs/recipes/custom-audit/custom-config.js)
* [pwmetrics](https://github.com/paulirish/pwmetrics/blob/v4.1.1/lib/perf-config.ts)

## Legacy Configs

Older versions of Lighthouse (pre-10.0) use a slightly different config format. The biggest difference is that the new configs do not include `passes`. If you want to load a page multiple times, we recommend creating a [user flow](https://github.com/GoogleChrome/lighthouse/blob/main/docs/user-flows.md).

- v9 configuration docs: https://github.com/GoogleChrome/lighthouse/blob/branch-9/docs/configuration.md

### `passes: Object[]`

The passes property controls how to load the requested URL and what information to gather about the page while loading. Each entry in the passes array represents one load of the page (e.g. 4 entries in `passes` will load the page 4 times), so be judicious about adding multiple entries here to avoid extending run times.

Each `passes` entry defines basic settings such as how long to wait for the page to load and whether to record a trace file. Additionally a list of **gatherers** to use is defined per pass. Gatherers can read information from the page to generate artifacts which are later used by audits to provide you with a Lighthouse report. For more information on implementing a custom gatherer and the role they play in building a Lighthouse report, refer to the [recipes](https://github.com/GoogleChrome/lighthouse/blob/main/docs/recipes/custom-audit). Also note that `artifacts.devtoolsLogs` will be automatically populated for every pass. Gatherers also have access to this data within the `afterPass` as `traceData.devtoolsLog` (However, most will find the higher-level `traceData.networkRecords` more useful).

For list of default pass values, see [our config constants](https://github.com/GoogleChrome/lighthouse/blob/main/core/config/constants.js).

#### Example
```js
{
passes: [
{
passName: 'fastPass',
gatherers: ['fast-gatherer'],
},
{
passName: 'slowPass',
recordTrace: true,
useThrottling: true,
networkQuietThresholdMs: 5000,
gatherers: ['slow-gatherer'],
}
]
}
```

#### Options
| Name | Type | Description |
| -- | -- | -- |
| passName | `string` | A unique identifier for the pass used in audits and during config extension. |
| recordTrace | `boolean` | Records a [trace](https://github.com/GoogleChrome/lighthouse/blob/main/docs/architecture.md#understanding-a-trace) of the pass when enabled. Available to gatherers during `afterPass` as `traceData.trace` and to audits in `artifacts.traces`. |
| useThrottling | `boolean` | Enables throttling of the pass when enabled. |
| pauseAfterLoadMs | `number` | The number of milliseconds to wait after the load event before the pass can continue. Used to ensure the page has had time for post-load JavaScript to execute before ending a trace. (Default: 0) |
| networkQuietThresholdMs | `number` | The number of milliseconds since the last network request to wait before the page should be considered to have reached 'network quiet'. Used to ensure the page has had time for the full waterfall of network requests to complete before ending a trace. (Default: 5000) |
| pauseAfterNetworkQuietMs | `number` | The number of milliseconds to wait after 'network quiet' before the pass can continue. Used to ensure the page has had time for post-network-quiet JavaScript to execute before ending a trace. (Default: 0) |
| blockedUrlPatterns | `string[]` | URLs of requests to block while loading the page. Basic wildcard support using `*`. |
| gatherers | `string[]` | The list of gatherers to run on this pass. This property is required and on extension will be concatenated with the existing set of gatherers. |

### Migrating to 10.0 format

1. Combine the gatherer lists in [`config.passes`](#passes-object) into [`config.artifacts`](#artifacts-object), giving each artifact a unique ID.
1. Remove [`config.passes`](#passes-object) property. Pass properties such as `pauseAfterLoadMs` are defined on `config.settings` in 10.0 configs.

### Using legacy configs in 10.0

The old config format can still be used in 10.0 but it's behind a separate path in the CLI and Node API.

**Use config file via CLI**
```sh
lighthouse --legacy-navigation --config-path=path/to/custom-config.js https://example.com
```

**Use config file via Node**
```js
import {legacyNavigation} from 'lighthouse';
import config from './path/to/custom-config.js';
await legacyNavigation('https://example.com/', {port: 9222}, config);
```
11 changes: 6 additions & 5 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ This file contains the configuration for your plugin. It can be called anything
**Example `plugin.js`**

```js
module.exports = {
export default {
// Additional audits to run on information Lighthouse gathered.
audits: [{path: 'lighthouse-plugin-cats/audits/has-cat-images.js'}],

Expand All @@ -99,7 +99,7 @@ These files contain the logic that will generate results for the Lighthouse repo
**Example `audits/has-cat-images.js`**

```js
const Audit = require('lighthouse').Audit;
import {Audit} = from 'lighthouse';

class CatAudit extends Audit {
static get meta() {
Expand Down Expand Up @@ -129,7 +129,7 @@ class CatAudit extends Audit {
}
}

module.exports = CatAudit;
export default CatAudit;
```

#### Run the plugin locally in development
Expand Down Expand Up @@ -164,6 +164,7 @@ Defines the display strings of the plugin's category and configures audit scorin
- `description: string` _OPTIONAL_ - A more detailed description of the category's purpose.
- `manualDescription: string` _OPTIONAL_ - A more detailed description of all of the manual audits in a plugin. Only use this if you've added manual audits.
- `auditRefs: Array<{id: string, weight: number, group?: string}>` **REQUIRED** - The list of audits to include in the plugin category along with their overall weight in the score of the plugin category. Each audit ref may optionally reference a group ID from `groups`.
- `supportedModes: string[]` _OPTIONAL_ - Which Lighthouse [modes](https://github.com/GoogleChrome/lighthouse/blob/master/docs/user-flows.md) this plugin supports. Category will support all modes if this is not provided.

#### `groups`

Expand Down Expand Up @@ -239,7 +240,7 @@ You might have noticed that a simple array of network requests is missing from t
See below for an example of an audit that processes network requests.

```js
const {Audit, NetworkRecords} = require('lighthouse');
import {Audit, NetworkRecords} from 'lighthouse';

class HeaderPoliceAudit {
static get meta() {
Expand Down Expand Up @@ -271,7 +272,7 @@ class HeaderPoliceAudit {
}
}

module.exports = HeaderPoliceAudit;
export default HeaderPoliceAudit;
```

## Best Practices
Expand Down
Loading