A comprehensive performance metrics collector for Playwright tests. Collect and analyze web vital metrics, network timing, and resource usage in your Playwright tests.
The playwright-performance-metrics plugin introduces a powerful way to measure and assert on web performance metrics directly in your Playwright tests. Unlike traditional end-to-end testing that focuses on functionality, this plugin enables teams to catch performance regressions early and maintain high performance standards through automated testing.
This plugin does not have external dependencies.
Comparison with playwright-lighthouse
Both plugins focus on performance testing, but they serve different purposes:
playwright-performance-metrics
- Real-time metrics during test execution
- Lower overhead - no need for separate Lighthouse runs
- Less configuration - minimal setup required for basic usage
- Specific metric focus - Core Web Vitals and key timings
- Test integration - natural fit in existing test flows
- Retry capability - built-in retriability mechanisms to ensure the metrics are collected
- Resource timing - detailed resource-level metrics
- Total bytes - size of all resources
- Time to first byte - detailed time to first byte metrics
playwright-lighthouse
- Comprehensive audits including SEO, accessibility
- Scoring system aligned with Lighthouse
- Static analysis of best practices
- Recommendations for improvements
- Performance simulation under various conditions
- Broader metrics beyond just performance
Key Features
- Real-time performance metrics collection during test execution
- Collect Web Vitals (LCP, CLS)
- Network timing metrics (TTFB, resource timing)
- Network condition emulation (3G, 4G, WiFi)
- Built-in retry mechanisms for reliable measurements
- Seamless integration with existing Playwright tests
- Type definitions for TypeScript support
- Configurable thresholds and timing options
- Resource usage tracking
The collectMetrics method returns the object containing the collected performance metrics:
PerformanceMetrics {
pageloadTiming: number
domCompleteTiming: number | null
resourceTiming: (resource: string) => PerformanceResourceTiming | undefined
largestContentfulPaint: number
totalBlockingTime: number
paint: { firstContentfulPaint: number; firstPaint: number }
cumulativeLayoutShift: number
totalBytes: number
timeToFirstByte: {
total: number
redirect: number
dns: number
connection: number
tls: number
wait: number
}
}
The initialize method accepts the predefined network condition preset (provided via DefaultNetworkPresets) or custom options and applies it to the current test run.
Available Metrics
Metric | Description | Typical Threshold |
---|---|---|
largestContentfulPaint | Time until largest content element is visible | < 2500ms |
totalBlockingTime | Sum of blocking time for long tasks | < 300ms |
cumulativeLayoutShift | Measure of visual stability | < 0.1 |
paint.firstContentfulPaint | Time until first meaningful content appears | < 1800ms |
paint.firstPaint | Time until first pixel is painted | < 1000ms |
pageloadTiming | Total page load time | < 3000ms |
domCompleteTiming | Time until DOM is fully loaded | < 2500ms |
resourceTiming | Time until resource is fully loaded | < 500ms |
totalBytes | Size of all resources | < 1.5 MB |
timeToFirstByte.total | Time to first byte | < 500ms |
timeToFirstByte.dns | DNS time | < 20ms |
timeToFirstByte.wait | Wait time | < 50ms |
timeToFirstByte.redirect | Redirect time | < 50ms |
timeToFirstByte.tls | TLS time | < 50ms |
timeToFirstByte.connection | Connection time | < 50ms |
npm install -D playwright-performance-metrics
Basic usage:
- Note: it is important to wait the completion of the page load before collecting metrics.
import { test } from '@playwright/test';
import { PerformanceMetricsCollector } from 'playwright-performance-metrics';
test('measure page performance', async ({ page }) => {
const collector = new PerformanceMetricsCollector();
await page.goto('https://example.com', { waitUntil: 'networkidle' })
const metrics = await collector.collectMetrics(page, {
timeout: 10000,
initialDelay: 1000
});
console.log('Performance metrics:', {
'First Paint': metrics.paint?.firstPaint,
'First Contentful Paint': metrics.paint?.firstContentfulPaint,
'Largest Contentful Paint': metrics.largestContentfulPaint,
'Cumulative Layout Shift': metrics.cumulativeLayoutShift
});
expect(metrics.pageloadTiming, 'Page load time is less than 2000ms').toBeLessThan(2000)
expect(metrics.domCompleteTiming, 'DOM Complete is less than 900ms').toBeLessThan(900)
expect(metrics.paint?.firstContentfulPaint, 'First Contentful Paint is less than 2000ms').toBeLessThan(2000)
expect(metrics.paint?.firstPaint, 'First Paint is less than 1000ms').toBeLessThan(1000)
expect(metrics.largestContentfulPaint, 'Largest Contentful Paint is less than 2500ms').toBeLessThan(2500)
expect(metrics.cumulativeLayoutShift, 'Cumulative Layout Shift is less than 0.1').toBeLessThan(0.1)
expect(metrics.totalBlockingTime, 'Total Blocking Time is less than 500ms').toBeLessThan(500)
expect(metrics.totalBytes, 'Total bytes is less than 1.5 MB').toBeLessThan(1024 * 1024 * 1.5)
expect(metrics.timeToFirstByte?.total, 'Time to first byte is less than 900ms').toBeLessThan(900)
expect(metrics.timeToFirstByte.dns, 'DNS time is less than 100ms').toBeLessThan(100)
expect(metrics.timeToFirstByte.wait, 'Wait time is less than 100ms').toBeLessThan(100)
expect(metrics.timeToFirstByte.redirect, 'Redirect time is less than 100ms').toBeLessThan(100)
expect(metrics.timeToFirstByte.tls, 'TLS time is less than 100ms').toBeLessThan(100)
expect(metrics.timeToFirstByte.connection, 'Connection time is less than 100ms').toBeLessThan(100)
})
With network emulation:
Library provides predefined presets for network conditions.
- REGULAR_4G
- SLOW_3G
- FAST_3G
- FAST_WIFI
import { DefaultNetworkPresets } from 'playwright-performance-metrics';
test('measure performance with slow 3G', async ({ page }) => {
const collector = new PerformanceMetricsCollector();
await collector.initialize(page, DefaultNetworkPresets.SLOW_3G)
await page.goto('https://example.com')
const metrics = await collector.collectMetrics(page, {
timeout: 30000
})
await collector.cleanup()
expect(slowNetworkMetrics.domCompleteTiming).toBeLessThan(25000)
console.log('Slow 3G metrics:', metrics)
})
With fixtures:
// fixture.ts
import { test as base, expect } from '@playwright/test'
import { PerformanceMetricsCollector } from 'playwright-performance-metrics'
const test = base.extend({
collector: async ({ page }, use) => {
const collector = new PerformanceMetricsCollector()
await use(collector)
}
})
export { test, expect }
// test.spec.ts
import { expect, test } from './fixture.ts'
test('measure page performance', async ({ page, collector }) => {
await page.goto('https://example.com', { waitUntil: 'networkidle' })
const metrics = await collector.collectMetrics(page)
expect(metrics.domCompleteTiming, 'DOM Complete is less than 900ms').toBeLessThan(900)
expect(metrics.paint?.firstContentfulPaint, 'First Contentful Paint is less than 2000ms').toBeLessThan(2000)})
})
For more examples see tests in the package repository - https://github.com/Valiantsin2021/playwright-performance-metrics
Main class for collecting performance metrics.
Provides following interfaces:
- DefaultNetworkPresets - network presets object
- initialize method
- cleanup method
- collectMetrics method
initialize
/**
* Initialize the collector with optional network conditions.
* @param page - Playwright Page instance to collect metrics from.
* @param networkConditions - Network conditions to emulate.
* @throws Error if CDP session creation fails.
*/
collectMetrics
/**
* Collect performance metrics from the page.
* @param page - Playwright page instance
* @param options - Options for metric collection.
* @returns Collected performance metrics.
*/
options:
/** Maximum time to wait for metrics collection (ms) */
timeout?: number
/** Maximum time to retry collecting metrics (ms) */
retryTimeout?: number
Available network presets:
REGULAR_4G
SLOW_3G
FAST_3G
FAST_WIFI
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details