> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/GoogleChrome/lighthouse/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How Lighthouse works internally: from Chrome DevTools Protocol through gatherers, audits, and report generation.

Lighthouse is a pipeline. A browser session drives Chrome over the DevTools Protocol, gatherers collect raw page data into artifacts, audits score individual features against those artifacts, and a report renderer turns the result into HTML.

## Pipeline overview

```mermaid theme={null}
flowchart LR
  A[Driver\nChrome DevTools Protocol] --> B[Gatherers\ncollect page data]
  B --> C[Raw Artifacts\nJSON snapshots]
  C --> D[Computed Artifacts\nderived on demand]
  C --> E[Audits\nscore single feature]
  D --> E
  E --> F[LHR\nLighthouse Result object]
  F --> G[Report\nclient-side HTML]
```

<Columns cols={2}>
  <Card title="Driver" icon="plug">
    Interfaces with Puppeteer and the Chrome DevTools Protocol (CDP) over WebSocket. Sends commands to Chrome and listens for protocol events. In the Chrome extension the same protocol is accessed via the `chrome.debugger` API.
  </Card>

  <Card title="Gatherers" icon="database">
    Use the Driver to collect information about the page during load. They produce three primary outputs when you run with `--gather-mode`: `artifacts.json`, `trace.json`, and `devtoolslog.json`. Gatherers do minimal post-processing.
  </Card>

  <Card title="Computed Artifacts" icon="calculator">
    Generated on demand from raw artifacts. They add additional meaning and are often shared across multiple audits. For example, `NetworkRecords` is derived from `DevtoolsLog` and reused by many audits without re-parsing the log.
  </Card>

  <Card title="Audits" icon="clipboard-check">
    Tests for a single feature, optimization, or metric. Each audit receives the artifacts it declared in `requiredArtifacts`, evaluates a test, and resolves to a numeric score between `0` and `1`.
  </Card>

  <Card title="LHR" icon="file-json">
    The Lighthouse Result object (LHR) is the structured JSON output of a run. It contains all audit results, scores, and metadata. See [Understanding Results](/api/understanding-results) for the full schema.
  </Card>

  <Card title="Report" icon="layout-dashboard">
    The report UI is created client-side from the LHR. The HTML report, JSON export, and CSV export are all generated from this single result object by `ReportGenerator`.
  </Card>
</Columns>

## Gathering outputs

Run Lighthouse with `--gather-mode` to inspect the three primary gathering outputs before audits run:

| File               | Contents                                                                         |
| ------------------ | -------------------------------------------------------------------------------- |
| `artifacts.json`   | Structured output from all gatherers                                             |
| `trace.json`       | Raw Chrome performance trace; view in DevTools Performance panel                 |
| `devtoolslog.json` | All DevTools Protocol events; primary signal for network requests and page state |

## Terminology

Understanding the naming used throughout Lighthouse helps when reading audit code or writing your own.

| Term                   | Definition                                                                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Category**           | A roll-up collection of audits and audit groups into a user-facing report section (e.g. `Best Practices`). Applies weighting and overall scoring. Examples: Accessibility, Best Practices. |
| **Audit title**        | Short user-visible title for the *successful* audit. e.g. "All image elements have `[alt]` attributes."                                                                                    |
| **Audit failureTitle** | Short user-visible title for a *failing* audit. e.g. "Some image elements do not have `[alt]` attributes."                                                                                 |
| **Audit description**  | Explains why the user should care about the audit — not necessarily how to fix it unless no external link exists. Markdown links are supported.                                            |

## Protocol details

The Chrome DevTools Protocol connection is maintained via WebSocket for the CLI. Some domains must be explicitly `enable()`d before they emit events. Once enabled, they flush any buffered state events.

<Warning>
  Event binding must be set up **before** calling `Domain.enable()`. Enabling a domain first and then binding misses any events that flushed during the enable call.
</Warning>

```js theme={null}
// will NOT work — events flushed during enable() are missed
driver.defaultSession.sendCommand('Security.enable').then(_ => {
  driver.defaultSession.on('Security.securityStateChanged', state => { /* ... */ });
});

// WILL work — binding is synchronous, enable() flushes into the bound handler
driver.defaultSession.on('Security.securityStateChanged', state => { /* ... */ });
driver.defaultSession.sendCommand('Security.enable');
```

## Understanding a trace

`core/lib/tracehouse/trace-processor.js` provides the core transformation of a raw Chrome trace into meaningful objects. Each trace event has:

* a monotonically increasing timestamp in microseconds
* a thread ID and process ID
* an optional duration in microseconds
* metadata such as event type, task name, and frame

### Raw trace event

```js theme={null}
{
  'pid': 41904,          // process ID
  'tid': 1295,           // thread ID
  'ts': 1676836141,      // timestamp in microseconds
  'ph': 'X',             // trace event type
  'cat': 'toplevel',     // trace category from which this event came
  'name': 'MessageLoop::RunTask', // human-readable description
  'dur': 64,             // duration of the task in microseconds
  'args': {},            // additional data such as frame when applicable
}
```

### Processed trace

The processed trace identifies key moments (navigation start, FCP, LCP, DOM content loaded, trace end) and calculates their times in milliseconds relative to navigation start.

```js theme={null}
{
  processEvents: [/* all trace events in the main process */],
  mainThreadEvents: [/* all trace events on the main thread */],
  timings: {
    timeOrigin: 0,                  // always 0 ms
    firstContentfulPaint: 150,      // ms after time origin
    /* other key moments */
    traceEnd: 16420,
  },
  timestamps: {
    timeOrigin: 623000000,          // microseconds, marks navigation start
    firstContentfulPaint: 623150000,
    /* other key moments */
    traceEnd: 639420000,
  },
}
```

<Tip>
  You can view `trace.json` directly in the Chrome DevTools Performance panel to visualize all trace events across processes and threads.
</Tip>

## Module dependency graph

The internal module dependencies of `core/index.js` show that `runner.js` orchestrates both the gather phase (via `navigationGather`, `snapshotGather`, `startTimespanGather`) and the audit phase (`Runner.audit`). The report generation step is fully separate and operates only on the serializable LHR.

```
cli \
      -- core/index.js ----> runner.js ----> [Gather / Audit]
clients /
```

For deeper reading on throttling simulation, see the [Throttling](/configuration/throttling) documentation.
