or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mdcore-auditing.mdindex.mdreport-generation.mduser-flows.md
tile.json

configuration.mddocs/

0

# Configuration and Extension

1

2

Lighthouse provides a comprehensive configuration system and extensibility framework for customizing audits, creating custom gatherers, and adapting the tool to specific testing requirements. This system enables deep customization while maintaining compatibility with the core Lighthouse architecture.

3

4

## Capabilities

5

6

### Configuration Interface

7

8

The main configuration interface that controls all aspects of Lighthouse behavior.

9

10

```javascript { .api }

11

interface LH.Config {

12

// Core configuration

13

extends?: 'lighthouse:default' | 'lighthouse:desktop' | string;

14

settings?: LH.Config.Settings;

15

16

// Audit configuration

17

audits?: LH.Config.AuditDefn[];

18

categories?: Record<string, LH.Config.Category>;

19

groups?: Record<string, LH.Config.Group>;

20

21

// Extension points

22

plugins?: string[];

23

passes?: LH.Config.Pass[];

24

gatherers?: LH.Config.GathererDefn[];

25

}

26

```

27

28

### Configuration Settings

29

30

Runtime settings that control Lighthouse execution behavior.

31

32

```javascript { .api }

33

interface LH.Config.Settings {

34

// Output configuration

35

output?: LH.OutputMode | LH.OutputMode[];

36

outputPath?: string;

37

locale?: string;

38

39

// Runtime configuration

40

maxWaitForFcp?: number;

41

maxWaitForLoad?: number;

42

pauseAfterFcpMs?: number;

43

pauseAfterLoadMs?: number;

44

networkQuietThresholdMs?: number;

45

cpuQuietThresholdMs?: number;

46

47

// Throttling configuration

48

throttlingMethod?: 'devtools' | 'simulate' | 'provided';

49

throttling?: LH.ThrottlingSettings;

50

51

// Device emulation

52

screenEmulation?: LH.Config.ScreenEmulationSettings;

53

emulatedUserAgent?: string;

54

55

// Audit filtering

56

onlyAudits?: string[];

57

skipAudits?: string[];

58

onlyCategories?: string[];

59

60

// Advanced options

61

disableStorageReset?: boolean;

62

disableDeviceEmulation?: boolean;

63

clearStorageTypes?: string[];

64

budgets?: LH.Budget[];

65

}

66

```

67

68

**Usage Examples:**

69

70

```javascript

71

import lighthouse, { defaultConfig, desktopConfig } from 'lighthouse';

72

73

// Basic custom configuration

74

const customConfig = {

75

extends: 'lighthouse:default',

76

settings: {

77

onlyCategories: ['performance', 'accessibility'],

78

throttlingMethod: 'simulate',

79

screenEmulation: {

80

mobile: false,

81

width: 1920,

82

height: 1080,

83

deviceScaleFactor: 1,

84

},

85

},

86

};

87

88

const result = await lighthouse('https://example.com', {}, customConfig);

89

90

// Desktop configuration

91

const result = await lighthouse('https://example.com', {}, desktopConfig);

92

93

// Performance-only configuration

94

const perfConfig = {

95

extends: 'lighthouse:default',

96

settings: {

97

onlyCategories: ['performance'],

98

throttling: {

99

rttMs: 40,

100

throughputKbps: 10240,

101

cpuSlowdownMultiplier: 1,

102

},

103

},

104

};

105

```

106

107

### Audit System

108

109

Framework for creating and configuring custom audits.

110

111

```javascript { .api }

112

/**

113

* Base class for creating custom audits

114

*/

115

class Audit {

116

/**

117

* Audit metadata

118

*/

119

static get meta(): LH.Audit.Meta;

120

121

/**

122

* Main audit logic

123

* @param artifacts - Collected artifacts from gatherers

124

* @param context - Audit execution context

125

* @returns Audit result with score and details

126

*/

127

static audit(

128

artifacts: LH.Artifacts,

129

context: LH.Audit.Context

130

): LH.Audit.Product | Promise<LH.Audit.Product>;

131

132

/**

133

* Generate audit result structure

134

* @param score - Audit score (0-1 or null)

135

* @param options - Additional result options

136

* @returns Formatted audit result

137

*/

138

static generateAuditResult(

139

score: number | null,

140

options?: {

141

displayValue?: string;

142

explanation?: string;

143

errorMessage?: string;

144

warnings?: string[];

145

details?: LH.Audit.Details;

146

}

147

): LH.Audit.Product;

148

}

149

```

150

151

**Custom Audit Example:**

152

153

```javascript

154

import { Audit } from 'lighthouse';

155

156

class CustomPerformanceAudit extends Audit {

157

static get meta() {

158

return {

159

id: 'custom-performance-audit',

160

title: 'Custom Performance Check',

161

description: 'Checks for custom performance criteria',

162

requiredArtifacts: ['traces', 'devtoolsLogs'],

163

};

164

}

165

166

static audit(artifacts, context) {

167

const traces = artifacts.traces[Audit.DEFAULT_PASS];

168

const devtoolsLogs = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];

169

170

// Custom audit logic

171

const customMetric = calculateCustomMetric(traces, devtoolsLogs);

172

const score = customMetric < 2000 ? 1 : customMetric < 4000 ? 0.5 : 0;

173

174

return Audit.generateAuditResult(score, {

175

displayValue: `${customMetric}ms`,

176

details: {

177

type: 'table',

178

headings: [{key: 'metric', text: 'Custom Metric'}],

179

items: [{metric: `${customMetric}ms`}],

180

},

181

});

182

}

183

}

184

185

// Configuration with custom audit

186

const config = {

187

extends: 'lighthouse:default',

188

audits: [CustomPerformanceAudit],

189

categories: {

190

performance: {

191

title: 'Performance',

192

auditRefs: [

193

{id: 'first-contentful-paint', weight: 10},

194

{id: 'custom-performance-audit', weight: 5},

195

],

196

},

197

},

198

};

199

```

200

201

### Gatherer System

202

203

Framework for creating custom data gatherers.

204

205

```javascript { .api }

206

/**

207

* Base class for creating custom gatherers

208

*/

209

class Gatherer {

210

/**

211

* Gatherer metadata

212

*/

213

meta: LH.Gatherer.GathererMeta;

214

215

/**

216

* Start instrumentation for data collection

217

* @param passContext - Gatherer execution context

218

*/

219

startInstrumentation(passContext: LH.Gatherer.Context): Promise<void> | void;

220

221

/**

222

* Start sensitive instrumentation (user interactions, etc.)

223

* @param passContext - Gatherer execution context

224

*/

225

startSensitiveInstrumentation(passContext: LH.Gatherer.Context): Promise<void> | void;

226

227

/**

228

* Stop sensitive instrumentation

229

* @param passContext - Gatherer execution context

230

*/

231

stopSensitiveInstrumentation(passContext: LH.Gatherer.Context): Promise<void> | void;

232

233

/**

234

* Stop instrumentation and finalize data collection

235

* @param passContext - Gatherer execution context

236

*/

237

stopInstrumentation(passContext: LH.Gatherer.Context): Promise<void> | void;

238

239

/**

240

* Get the collected artifact

241

* @param passContext - Gatherer execution context

242

* @returns Collected artifact data

243

*/

244

getArtifact(passContext: LH.Gatherer.Context): LH.Gatherer.PhaseResult;

245

}

246

```

247

248

**Custom Gatherer Example:**

249

250

```javascript

251

import { Gatherer } from 'lighthouse';

252

253

class CustomMetricsGatherer extends Gatherer {

254

constructor() {

255

super();

256

this.meta = {

257

supportedModes: ['navigation', 'timespan', 'snapshot'],

258

};

259

}

260

261

async startInstrumentation(context) {

262

// Initialize data collection

263

this.customData = {};

264

}

265

266

async getArtifact(context) {

267

const {driver} = context;

268

269

// Collect custom metrics using Chrome DevTools Protocol

270

const customMetrics = await driver.executionContext.evaluate(() => {

271

return {

272

customLoadTime: performance.now(),

273

resourceCount: document.querySelectorAll('img, script, link').length,

274

domComplexity: document.querySelectorAll('*').length,

275

};

276

}, {useIsolation: true});

277

278

return customMetrics;

279

}

280

}

281

282

// Configuration with custom gatherer

283

const config = {

284

extends: 'lighthouse:default',

285

passes: [{

286

passName: 'defaultPass',

287

gatherers: ['custom-metrics'],

288

}],

289

gatherers: [{

290

path: CustomMetricsGatherer,

291

options: {},

292

}],

293

};

294

```

295

296

### Plugin System

297

298

Lighthouse supports plugins for packaging custom audits and gatherers.

299

300

```javascript { .api }

301

// Plugin structure

302

interface LH.Plugin {

303

audits: LH.Config.AuditDefn[];

304

groups?: Record<string, LH.Config.Group>;

305

category: LH.Config.Category;

306

}

307

```

308

309

**Plugin Example:**

310

311

```javascript

312

// lighthouse-plugin-custom.js

313

module.exports = {

314

audits: [

315

{path: 'lighthouse-plugin-custom/audits/custom-audit.js'},

316

],

317

groups: {

318

'custom-group': {

319

title: 'Custom Checks',

320

description: 'Custom performance and functionality checks',

321

},

322

},

323

category: {

324

title: 'Custom Category',

325

description: 'Custom audits for specialized requirements',

326

auditRefs: [

327

{id: 'custom-audit', weight: 1, group: 'custom-group'},

328

],

329

},

330

};

331

332

// Configuration using plugin

333

const config = {

334

extends: 'lighthouse:default',

335

plugins: ['lighthouse-plugin-custom'],

336

};

337

```

338

339

### Budget Configuration

340

341

Performance budgets for monitoring resource usage and performance metrics.

342

343

```javascript { .api }

344

interface LH.Budget {

345

path?: string; // URL path pattern

346

resourceSizes?: LH.Budget.ResourceBudget[];

347

resourceCounts?: LH.Budget.ResourceBudget[];

348

timings?: LH.Budget.TimingBudget[];

349

}

350

351

interface LH.Budget.ResourceBudget {

352

resourceType: LH.Budget.ResourceType;

353

budget: number; // Size in bytes or count

354

}

355

356

interface LH.Budget.TimingBudget {

357

metric: LH.Budget.TimingMetric;

358

budget: number; // Time in milliseconds

359

}

360

```

361

362

**Budget Example:**

363

364

```javascript

365

const budgetConfig = {

366

extends: 'lighthouse:default',

367

settings: {

368

budgets: [{

369

path: '/*', // Apply to all pages

370

resourceSizes: [

371

{resourceType: 'script', budget: 500000}, // 500KB JS

372

{resourceType: 'image', budget: 1000000}, // 1MB images

373

{resourceType: 'stylesheet', budget: 100000}, // 100KB CSS

374

],

375

resourceCounts: [

376

{resourceType: 'script', budget: 10}, // Max 10 scripts

377

{resourceType: 'image', budget: 50}, // Max 50 images

378

],

379

timings: [

380

{metric: 'first-contentful-paint', budget: 2000}, // 2s FCP

381

{metric: 'largest-contentful-paint', budget: 4000}, // 4s LCP

382

],

383

}],

384

},

385

};

386

```

387

388

## Advanced Configuration Patterns

389

390

### Environment-Specific Configurations

391

392

```javascript

393

// Development configuration

394

const devConfig = {

395

extends: 'lighthouse:default',

396

settings: {

397

throttlingMethod: 'provided', // No throttling for local dev

398

screenEmulation: {disabled: true}, // Use actual viewport

399

onlyCategories: ['performance'], // Focus on performance

400

},

401

};

402

403

// CI configuration

404

const ciConfig = {

405

extends: 'lighthouse:default',

406

settings: {

407

throttlingMethod: 'simulate', // Consistent throttling

408

maxWaitForLoad: 60000, // Longer timeout for CI

409

output: ['json', 'html'], // Multiple outputs

410

},

411

};

412

413

// Production monitoring configuration

414

const prodConfig = {

415

extends: 'lighthouse:default',

416

settings: {

417

throttlingMethod: 'simulate',

418

throttling: { // Production-like conditions

419

rttMs: 150,

420

throughputKbps: 1638,

421

cpuSlowdownMultiplier: 4,

422

},

423

budgets: [/* performance budgets */],

424

},

425

};

426

```

427

428

### Configuration Validation

429

430

```javascript

431

function validateConfig(config) {

432

const errors = [];

433

434

// Validate required fields

435

if (config.audits && !Array.isArray(config.audits)) {

436

errors.push('config.audits must be an array');

437

}

438

439

// Validate category references

440

if (config.categories) {

441

Object.values(config.categories).forEach(category => {

442

category.auditRefs?.forEach(auditRef => {

443

const auditExists = config.audits?.some(audit =>

444

audit.path?.includes(auditRef.id) || audit === auditRef.id

445

);

446

if (!auditExists) {

447

errors.push(`Audit ${auditRef.id} referenced but not defined`);

448

}

449

});

450

});

451

}

452

453

return errors;

454

}

455

456

// Usage

457

const configErrors = validateConfig(customConfig);

458

if (configErrors.length > 0) {

459

throw new Error(`Configuration errors: ${configErrors.join(', ')}`);

460

}

461

```

462

463

### Dynamic Configuration Generation

464

465

```javascript

466

function createDynamicConfig(options = {}) {

467

const baseConfig = {

468

extends: 'lighthouse:default',

469

settings: {

470

throttlingMethod: options.throttling || 'simulate',

471

},

472

};

473

474

// Add mobile-specific settings

475

if (options.mobile) {

476

baseConfig.settings.screenEmulation = {

477

mobile: true,

478

width: 375,

479

height: 667,

480

deviceScaleFactor: 2,

481

};

482

}

483

484

// Add category filtering

485

if (options.categories) {

486

baseConfig.settings.onlyCategories = options.categories;

487

}

488

489

// Add custom audits

490

if (options.customAudits) {

491

baseConfig.audits = options.customAudits;

492

}

493

494

return baseConfig;

495

}

496

497

// Usage

498

const mobileConfig = createDynamicConfig({

499

mobile: true,

500

categories: ['performance', 'accessibility'],

501

throttling: 'simulate',

502

});

503

```

504

505

## Error Handling and Debugging

506

507

### Configuration Debugging

508

509

```javascript

510

// Debug configuration loading

511

import lighthouse, { defaultConfig } from 'lighthouse';

512

513

console.log('Default config structure:', JSON.stringify(defaultConfig, null, 2));

514

515

try {

516

const result = await lighthouse('https://example.com', {}, customConfig);

517

console.log('Configuration applied successfully');

518

} catch (error) {

519

if (error.code === 'INVALID_CONFIG') {

520

console.error('Configuration error:', error.message);

521

console.error('Config details:', error.details);

522

} else {

523

console.error('Lighthouse error:', error.message);

524

}

525

}

526

```

527

528

### Audit and Gatherer Debugging

529

530

```javascript

531

// Enable debug logging for custom components

532

class DebugAudit extends Audit {

533

static audit(artifacts, context) {

534

console.log('Debug audit running with artifacts:', Object.keys(artifacts));

535

console.log('Audit context:', context);

536

537

try {

538

// Audit logic

539

const result = performAuditLogic(artifacts);

540

console.log('Audit result:', result);

541

return result;

542

} catch (error) {

543

console.error('Audit error:', error);

544

return Audit.generateAuditResult(null, {

545

errorMessage: error.message,

546

});

547

}

548

}

549

}

550

```