0
# Report Generation
1
2
Lighthouse report generation transforms audit results into various output formats for analysis, sharing, and integration with other tools. The reporting system supports multiple formats and provides both programmatic and file-based output options.
3
4
## Capabilities
5
6
### Generate Report Function
7
8
Generates formatted reports from Lighthouse results in multiple output formats.
9
10
```javascript { .api }
11
/**
12
* Generate formatted report from Lighthouse results
13
* @param result - Lighthouse result or flow result to format
14
* @param format - Output format (html, json, csv)
15
* @returns Generated report as string
16
*/
17
function generateReport(
18
result: LH.Result | LH.FlowResult,
19
format?: LH.OutputMode
20
): string;
21
```
22
23
**Usage Examples:**
24
25
```javascript
26
import lighthouse, { generateReport } from 'lighthouse';
27
28
// Run audit and generate reports
29
const runnerResult = await lighthouse('https://example.com', {
30
port: chrome.port,
31
});
32
33
// Generate HTML report (default)
34
const htmlReport = generateReport(runnerResult.lhr);
35
console.log('HTML report length:', htmlReport.length);
36
37
// Generate JSON report
38
const jsonReport = generateReport(runnerResult.lhr, 'json');
39
const parsed = JSON.parse(jsonReport);
40
console.log('Performance score:', parsed.categories.performance.score);
41
42
// Generate CSV report
43
const csvReport = generateReport(runnerResult.lhr, 'csv');
44
console.log('CSV report:', csvReport);
45
```
46
47
### Flow Report Generation
48
49
Generate reports specifically for user flow results with multi-step analysis.
50
51
```javascript
52
import { startFlow, generateReport } from 'lighthouse';
53
54
const flow = await startFlow(page, {name: 'User Journey'});
55
await flow.navigate('https://example.com');
56
await flow.startTimespan();
57
// ... user interactions
58
await flow.endTimespan();
59
60
const flowResult = await flow.createFlowResult();
61
62
// Generate flow report (HTML format optimized for flows)
63
const flowHtmlReport = generateReport(flowResult, 'html');
64
65
// Generate flow JSON report
66
const flowJsonReport = generateReport(flowResult, 'json');
67
```
68
69
### Report Saving and Management
70
71
**File Output:**
72
73
```javascript
74
import fs from 'fs';
75
import lighthouse, { generateReport } from 'lighthouse';
76
77
const runnerResult = await lighthouse('https://example.com', {
78
port: chrome.port,
79
output: ['html', 'json'], // Generate multiple formats
80
outputPath: './lighthouse-report', // Base output path
81
});
82
83
// Reports are automatically saved when outputPath is provided
84
// Files: lighthouse-report.html, lighthouse-report.json
85
86
// Manual saving with custom names
87
const htmlReport = generateReport(runnerResult.lhr, 'html');
88
fs.writeFileSync('./custom-report.html', htmlReport);
89
90
const jsonReport = generateReport(runnerResult.lhr, 'json');
91
fs.writeFileSync('./custom-report.json', jsonReport);
92
```
93
94
### Programmatic Report Analysis
95
96
**Extract Key Metrics:**
97
98
```javascript
99
const runnerResult = await lighthouse('https://example.com');
100
const jsonReport = generateReport(runnerResult.lhr, 'json');
101
const lhr = JSON.parse(jsonReport);
102
103
// Extract performance metrics
104
const metrics = {
105
performanceScore: lhr.categories.performance.score * 100,
106
fcp: lhr.audits['first-contentful-paint'].numericValue,
107
lcp: lhr.audits['largest-contentful-paint'].numericValue,
108
cls: lhr.audits['cumulative-layout-shift'].numericValue,
109
tbt: lhr.audits['total-blocking-time'].numericValue,
110
si: lhr.audits['speed-index'].numericValue,
111
};
112
113
console.log('Performance Metrics:', metrics);
114
```
115
116
**Extract Audit Details:**
117
118
```javascript
119
const jsonReport = generateReport(runnerResult.lhr, 'json');
120
const lhr = JSON.parse(jsonReport);
121
122
// Get failed audits
123
const failedAudits = Object.entries(lhr.audits)
124
.filter(([id, audit]) => audit.score !== null && audit.score < 1)
125
.map(([id, audit]) => ({
126
id,
127
title: audit.title,
128
description: audit.description,
129
score: audit.score,
130
displayValue: audit.displayValue,
131
}));
132
133
console.log('Failed audits:', failedAudits);
134
```
135
136
## Output Formats
137
138
### HTML Format
139
140
The HTML format creates an interactive, comprehensive report with visualizations.
141
142
```javascript { .api }
143
// HTML report features:
144
// - Interactive performance timeline
145
// - Expandable audit details
146
// - Opportunity recommendations
147
// - Diagnostic information
148
// - Screenshot and filmstrip view
149
// - Treemap for bundle analysis
150
151
const htmlReport = generateReport(result, 'html');
152
// Returns: Complete HTML document with embedded CSS/JS
153
```
154
155
**HTML Report Characteristics:**
156
- Self-contained HTML file with embedded assets
157
- Interactive charts and visualizations
158
- Expandable sections for detailed audit information
159
- Performance timeline and metrics summary
160
- Screenshot galleries and filmstrip views
161
- Accessibility tree visualization for a11y audits
162
163
### JSON Format
164
165
The JSON format provides machine-readable results for programmatic analysis.
166
167
```javascript { .api }
168
// JSON report structure:
169
interface LH.Result {
170
lhr: LH.LighthouseResult; // Complete audit results
171
artifacts?: LH.Artifacts; // Raw collected data
172
report: string; // HTML report string
173
}
174
175
const jsonReport = generateReport(result, 'json');
176
// Returns: Stringified JSON with complete audit data
177
```
178
179
**JSON Report Structure:**
180
```javascript
181
{
182
"audits": { // Individual audit results
183
"first-contentful-paint": {
184
"id": "first-contentful-paint",
185
"title": "First Contentful Paint",
186
"score": 0.99,
187
"numericValue": 1234,
188
"displayValue": "1.2 s"
189
}
190
},
191
"categories": { // Category scores
192
"performance": {
193
"id": "performance",
194
"title": "Performance",
195
"score": 0.95,
196
"auditRefs": [...]
197
}
198
},
199
"configSettings": {...}, // Configuration used
200
"environment": {...}, // Test environment info
201
"fetchTime": "2023-...", // Timestamp
202
"finalUrl": "https://...", // Final URL after redirects
203
"timing": {...} // Performance timing data
204
}
205
```
206
207
### CSV Format
208
209
The CSV format provides spreadsheet-compatible tabular data.
210
211
```javascript { .api }
212
const csvReport = generateReport(result, 'csv');
213
// Returns: CSV string with audit results in tabular format
214
```
215
216
**CSV Report Structure:**
217
- Header row with column names
218
- One row per audit with key metrics
219
- Columns: category, audit name, score, value, units
220
- Suitable for data analysis and reporting tools
221
222
## Advanced Report Customization
223
224
### Custom Report Templates
225
226
While Lighthouse doesn't provide direct template customization, you can post-process the JSON output:
227
228
```javascript
229
const jsonReport = generateReport(runnerResult.lhr, 'json');
230
const lhr = JSON.parse(jsonReport);
231
232
// Create custom summary report
233
const customReport = {
234
url: lhr.finalUrl,
235
timestamp: lhr.fetchTime,
236
scores: {
237
performance: lhr.categories.performance.score * 100,
238
accessibility: lhr.categories.accessibility.score * 100,
239
bestPractices: lhr.categories['best-practices'].score * 100,
240
seo: lhr.categories.seo.score * 100,
241
},
242
coreWebVitals: {
243
lcp: lhr.audits['largest-contentful-paint'].displayValue,
244
fid: lhr.audits['max-potential-fid']?.displayValue || 'N/A',
245
cls: lhr.audits['cumulative-layout-shift'].displayValue,
246
},
247
opportunities: Object.values(lhr.audits)
248
.filter(audit => audit.details && audit.details.type === 'opportunity')
249
.map(audit => ({
250
title: audit.title,
251
savings: audit.details.overallSavingsMs,
252
description: audit.description,
253
})),
254
};
255
256
console.log('Custom report:', JSON.stringify(customReport, null, 2));
257
```
258
259
### Batch Report Generation
260
261
```javascript
262
const urls = [
263
'https://example.com',
264
'https://example.com/about',
265
'https://example.com/contact',
266
];
267
268
const reports = [];
269
270
for (const url of urls) {
271
const runnerResult = await lighthouse(url, {port: chrome.port});
272
const jsonReport = generateReport(runnerResult.lhr, 'json');
273
274
reports.push({
275
url,
276
timestamp: new Date().toISOString(),
277
report: JSON.parse(jsonReport),
278
});
279
}
280
281
// Generate combined summary
282
const summary = reports.map(({url, report}) => ({
283
url,
284
performance: report.categories.performance.score * 100,
285
accessibility: report.categories.accessibility.score * 100,
286
bestPractices: report.categories['best-practices'].score * 100,
287
seo: report.categories.seo.score * 100,
288
}));
289
290
console.table(summary);
291
```
292
293
## Integration Patterns
294
295
### CI/CD Integration
296
297
```javascript
298
// Example for CI/CD pipeline
299
import lighthouse, { generateReport } from 'lighthouse';
300
import fs from 'fs';
301
302
async function auditForCI(url, thresholds = {}) {
303
const runnerResult = await lighthouse(url, {
304
port: chrome.port,
305
output: 'json',
306
throttlingMethod: 'simulate',
307
});
308
309
const jsonReport = generateReport(runnerResult.lhr, 'json');
310
const lhr = JSON.parse(jsonReport);
311
312
// Check against thresholds
313
const scores = {
314
performance: lhr.categories.performance.score * 100,
315
accessibility: lhr.categories.accessibility.score * 100,
316
bestPractices: lhr.categories['best-practices'].score * 100,
317
seo: lhr.categories.seo.score * 100,
318
};
319
320
const failures = Object.entries(thresholds)
321
.filter(([category, threshold]) => scores[category] < threshold)
322
.map(([category, threshold]) =>
323
`${category}: ${scores[category]} < ${threshold}`
324
);
325
326
// Save report for artifacts
327
fs.writeFileSync('./lighthouse-ci-report.json', jsonReport);
328
329
if (failures.length > 0) {
330
throw new Error(`Performance thresholds failed: ${failures.join(', ')}`);
331
}
332
333
return scores;
334
}
335
336
// Usage in CI
337
try {
338
const scores = await auditForCI('https://staging.example.com', {
339
performance: 90,
340
accessibility: 95,
341
bestPractices: 90,
342
seo: 95,
343
});
344
console.log('All thresholds passed:', scores);
345
} catch (error) {
346
console.error('CI audit failed:', error.message);
347
process.exit(1);
348
}
349
```
350
351
### Monitoring Dashboard Integration
352
353
```javascript
354
// Example for sending results to monitoring system
355
async function sendToMonitoring(url) {
356
const runnerResult = await lighthouse(url);
357
const jsonReport = generateReport(runnerResult.lhr, 'json');
358
const lhr = JSON.parse(jsonReport);
359
360
const metrics = {
361
timestamp: Date.now(),
362
url: lhr.finalUrl,
363
performance_score: lhr.categories.performance.score,
364
fcp: lhr.audits['first-contentful-paint'].numericValue,
365
lcp: lhr.audits['largest-contentful-paint'].numericValue,
366
cls: lhr.audits['cumulative-layout-shift'].numericValue,
367
tbt: lhr.audits['total-blocking-time'].numericValue,
368
};
369
370
// Send to your monitoring system
371
await fetch('https://monitoring.example.com/api/lighthouse', {
372
method: 'POST',
373
headers: {'Content-Type': 'application/json'},
374
body: JSON.stringify(metrics),
375
});
376
377
return metrics;
378
}
379
```
380
381
## Error Handling
382
383
```javascript
384
try {
385
const runnerResult = await lighthouse('https://example.com');
386
387
// Check for runtime errors before generating report
388
if (runnerResult.lhr.runtimeError) {
389
console.error('Lighthouse runtime error:', runnerResult.lhr.runtimeError);
390
return null;
391
}
392
393
const htmlReport = generateReport(runnerResult.lhr, 'html');
394
const jsonReport = generateReport(runnerResult.lhr, 'json');
395
396
return { htmlReport, jsonReport };
397
398
} catch (error) {
399
console.error('Report generation failed:', error.message);
400
throw error;
401
}
402
```