Performance Testing using Playwright
On This Page What is Performance Testing in the Context of Playwright?January 30, 2026 · 16 min read · Tool Comparison
What do you do when all your UI tests are unripened, yet your coating nevertheless feels slow to user? It & # 8217; s a frustrative situation-and one most squad run into at some point. In fact, research shows that nearly 39 % of user abandon a site if images or content take too long to load-meaning performance isn & # 8217; t just a technical concern, it & # 8217; s a and business-impact fear. Yet traditional UI automation rarely highlights these problems. confirm whether things work, but not how fast they work. That & # 8217; s where becomes surprisingly potent. While not a full-scale tool, it yield you deep admittance to browser-level performance signals. Performance prove using Playwright focuses on capturing real browser-level performance signals during automated UI workflows. It help teams measure how fast page load, render, and respond from an actual user & # 8217; s perspective. How Playwright Facilitates Performance Testing: Key Considerations for Playwright Performance Testing This clause research how Playwright fits into execution examination, the metrics you can capture, how to structure performance-focused test, and how to ensure reliable, meaningful results in 2026 and beyond. in Playwright is all about measuring how fast your application behaves from a real exploiter & # 8217; s perspective, not how it execute under heavy load or traffic. While Playwright isn & # 8217; t meant for feign thousands of virtual users, it surpass at capturing browser-level execution signal during genuine user flow. Think of it as reply questions like: Playwright access the browser & # 8217; s built-in performance APIs, network events, and provide timelines to break metrics that directly impact user experience. This includes navigation timings, web waterfalls, CPU usage, JavaScript execution time, and UI rendering hold. In little, Playwright helps you validate not precisely whether something works-but how efficiently it works when a real user interacts with your app. Read More: Playwright gives you access to a extensive orbit of browser-generated execution information, allowing you to realise how your coating behaves during real user interactions. These metrics help you identify bottlenecks in loading, interpreting, network activity, and script execution. 1. Navigation Timings Playwright can extract detailed timing around each phase of page load, include: These metrics show incisively where delays occur during pilotage. 2. Rendering Metrics (Paint & amp; Layout Events) Using browser execution APIs and CDP, you can mensurate: These reveal how quickly content becomes visible and stable for users. 3. Network Timing & amp; Payload Metrics Playwright can track every request and reply, countenance you measure: This helps place which network calls slow down page execution. 4. JavaScript Execution Metrics Through CDP, Playwright gives visibility into: These metrics facilitate pinpoint heavy scripts that delay interactivity. 5. HAR (HTTP Archive) Data Playwright can generate HAR file showing a accomplished network waterfall, helping you diagnose slow assets, redirects, caching issues, and chokepoint in the loading succession. 6. Browser Traces Trace files reveal: Utile for deep performance profile during debug. Collecting these metric locally is utilitarian, but browser execution can vary widely across devices, OS versions, and. Running Playwright performance tests on supporter you formalise these metrics on real browsers and real devices, ensuring your execution brainstorm reflect what exploiter actually experience in product. Playwright doesn & # 8217; t position itself as a dedicated performance/load tool, but it exposes enough hooks into the browser to let you enamor meaningful performance data. Depending on the depth of insight you need, you can mix and match the methods below. Playwright can evaluate code inside the page and read the browser & # 8217; s built-in Performance API, include piloting and resource timings. // Resource timings (scripts, images, CSS, XHR, etc.) This is useful for measuring page burden time, DOMContentLoaded, and how long key imagination take to load. For Chromium-based browser, Playwright can open a CDP (Chrome DevTools Protocol) session to collect low-level performance metrics like CPU usage, JS performance time, and & # 8220; long tasks & # 8221;. await client.send (& # 8216; Performance.enable & # 8217;); console.log (metrics); CDP is ideal when you need deeper visibility into JavaScript performance, main-thread blocking, or CPU-heavy operations. Playwright can record HAR (HTTP Archive) files at the setting level, capturing a complete network waterfall: timing, redirects, lading size, and status codification. const page = await context.newPage (); // HAR is written when the setting is closed HAR files are perfect for analyse slow requests, turgid assets, inefficient caching, and overall network behavior. Tracing gives you a detailed timeline of each test run, including actions, snap, and network event. While not a & # 8220; measured & # 8221; by itself, it & # 8217; s extremely helpful for investigating slow steps. await context.tracing.start ({ const page = await context.newPage (); // & # 8230; run your flow & # 8230; await context.tracing.stop ({path: & # 8216; trace.zip & # 8217;}); You can open the trace later with Playwright & # 8217; s trace viewer to see exactly where clip was spent during navigation and interactions. For business-critical flows (e.g., hunt, checkout, add-to-cart), you can use custom-made marks and measures via the Performance API. // Perform user action (s) you want to quantify await page.evaluate (() = & gt; { const measures = await page.evaluate (() = & gt; { console.log (measures); This lets you precisely mensurate how long specific user journeys take, not merely foliate loads. Read More: To get reliable and quotable performance results with Playwright, you need a stable and the right configuration. The measure below ascertain that the metrics you collect are reproducible, meaningful, and adjust with how existent browsers carry. 1. Install Playwright and the Test Runner Use the recommended initializer: This establish: 2. Configure a Consistent Test Environment Create or update your playwright.config.ts to define stable browser conditions: This ensures deterministic conditions, since fluctuation in viewport, timezone, or render background can significantly impact performance metrics. 3. Disable Animations and Transitions Animations cause fluctuations in paint/render timings. Disable them globally: This ensures paint timestamps are stable across runs. For autonomous testing across multiple user personas, check out SUSATest — it explores your app like 10 different real users. 4. Enable HAR Recording (Network Waterfall) To capture detailed network timings: The HAR file is saved when context closes. 5. Enable Tracing for End-to-End Performance Visualization Playwright line furnish UI snapshots + a timeline of events: After the test: 6. Enable CDP for Deep Performance Metrics (Chromium Only) For CPU utilization, JS execution clip, and long-task detection: 7. Extract Performance API Metrics Capture browser-native metrics: Collect resource timing similarly: 8. Run Tests in a Stable Environment Always run execution tests: Example: This cut disturbance from OS rendering or UI overhead. 9. Store and Track Performance Baselines Use logs, JSON export, or your CI system to track changes over time. Example expectation: This helps detect regressions early. Read More: Once your environment is stable, you can start writing performance-focused exam that quantify how fast your application oodles and responds. The idea is simple: run a real user flow in the browser, capture metrics, and assert against performance expectations. 1. Measure Canonic Page Load Time A quick way to detect regressions is to clip page.goto (). 2. Capture Navigation Timing Metrics Use the Performance API for accurate browser-generated timings. const datum = await page.evaluate (() = & gt; { wait (data.dcl) .toBeLessThan (2000); 3. Measure a Specific User Flow Custom marks let you time real interactions like search, add-to-cart, or checkout. const duration = await page.evaluate (async () = & gt; { await page.fill (& # 8216; # lookup & # 8217;, & # 8216; playwright & # 8217;); const t = await page.evaluate (() = & gt; { await (t) .toBeLessThan (1500); 4. Collect Deep Metrics via CDP (Chromium Only) For CPU/JS-level profiling: Read More: Once your tests depart producing prosody, analyzing them correctly is essential to identifying bottlenecks and spotting regression. Focus on these key areas: 1. Compare Against Baselines Establish expected performance door (e.g., max load time, DCL, flow duration) and compare each test run against them. 2. Look for Trends, Not Spikes Performance is inherently noisy, so rely on patterns. 3. Use Logs to Find the Slow Point Your test logs reveal which milestone is slow: 4. Visualize Metrics Over Time Storing results in CI or performance dashboards aid you spot regressions betimes. 5. Correlate with Real User Data Semisynthetic tests show potential issues, but validate them using: If synthetic and real-user metric differ, review differences in mesh, device, and environment settings. 6. Identify Root Causes Once a slowdown is confirmed: Analyzing resolution this way aid you prioritize pickle that deliver the highest execution impact. Read More: Once your performance trial are stable topically, the future step is to run them mechanically on every change. Integrating them into your turns execution from a one-off activity into a continuous quality gate. 1. Separate Performance Tests From Functional Tests Keep execution tests logically isolated so they don & # 8217; t slow down every single run. 2. Add a Dedicated Performance Stage in CI Create a specific point (or job) in your CI pipeline that runs test: perf. Typical form: Key checks: 3. Use Stable, Reproducible Test Environments Performance numbers are only meaningful if the surround is consistent. If you & # 8217; re using a cloud grid like BrowserStack Automate, run execution tests onfixed device/OS/browser combinationsand keep those configs versioned in your repo. 4. Export and Store Metrics From Each Run Don & # 8217; t rely only on console logs-export metric in a machine-readable format. This let you to visualize trends and detect slow impetus over days/weeks. 5. Define Clear Failure Criteria and Alerts Make execution a first-class & # 8220; quality gate & # 8221; in the line. When door are breached: That way, performance fixation are catch early-just like failing unit or UI tests-and become component of normal development workflow instead of a one-time exercise. Read More: Performance trial are only worthful when their results are ordered and repeatable. To reduce noise and ensure trustworthy prosody, focus on stabilizing the environment and standardizing how tests run. 1. Control the Test Environment This eliminates variability get by dissent machine performance or browser engine updates. 2. Standardize Browser Settings Uniform browser weather produce more stable timing values across footrace. 3. Stabilize Network and Test Data Consistent meshwork and data province prevent sudden capitulum caused by external ingredient. 4. Warm-Up Before Measuring This avoids false slowdowns caused by first-load cache doings. 5. Use Multiple Runs and Median Values This reduces flakiness and makes your alerts more true. 6. Make Failures Easy to Diagnose Good helps rapidly identify whether a slowdown is real or environmental. Read More: Playwright is powerful for lightweight browser performance checks, but it & # 8217; s not suited for every performance scenario. Avoid habituate it in the following cases: BrowserStack Automate provides a stable, cloud-based environment that makes it easier to run Playwright performance checks consistently across different browsers and devices. Performance testing with Playwright gives team a pragmatic, code-friendly way to mensurate how fast their coating loads and responds during real exploiter flows. By capturing browser-level metrics, instrumenting custom interactions, and integrating test into, you can detect fixation early-long before they reach production. For execution results to be meaningful, they must be consistent. Stabilizing your environment, standardizing browser background, and utilize quotable data figure guarantee your metrics ruminate real issue, not noise. And when you & # 8217; re ready to scale, platforms like BrowserStack Automate help you run Playwright exam across real browser and devices, making your execution checks more reliable and production-aligned. In the end, Playwright doesn & # 8217; t replace full-scale load testing, but it occupy a critical gap by bringing lightweight, developer-friendly performance validation directly into your testing workflow. With the right frame-up and tooling, you can build a fast, reactive application-and proceed it that way with every release. Tool Comparisons: On This Page # Ask-and-Contributeabout this topic with our Discord community. Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed. Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.Performance Testing using Playwright
Overview
What is Performance Testing in the Context of Playwright?
Key Performance Metrics You Can Capture With Playwright
Methods to Perform Performance Testing in Playwright
1. Using Browser Performance APIs
// Navigation timing
const navigationEntries = await page.evaluate (() = & gt; {
homecoming performance.getEntriesByType (& # 8216; navigation & # 8217;);
});
const resourceEntries = await page.evaluate (() = & gt; {
homecoming performance.getEntriesByType (& # 8216; resource & # 8217;);
});2. Using Chrome DevTools Protocol (CDP) for Deep Metrics (Chromium)
const client = await page.context () .newCDPSession (page);
const metrics = await client.send (& # 8216; Performance.getMetrics & # 8217;);3. Recording HAR Files for Network Performance
const context = await browser.newContext ({
recordHar: {way: & # 8216; network.har & # 8217;}
});
await page.goto (& # 8216; https: //example.com & # 8217;);
await context.close ();4. Using Playwright Tracing for Timeline + Visual Insights
const context = await browser.newContext ();
screenshots: true,
snapshots: true,
sources: true
});
await page.goto (& # 8216; https: //example.com & # 8217;);5. Instrumenting Custom Performance Marks and Measures
await page.evaluate (() = & gt; {
performance.mark (& # 8216; flow-start & # 8217;);
});
await page.click (& # 8216; button # checkout & # 8217;);
performance.mark (& # 8216; flow-end & # 8217;);
performance.measure (& # 8216; checkout-flow & # 8217;, & # 8216; flow-start & # 8217;, & # 8216; flow-end & # 8217;);
});
return performance.getEntriesByName (& # 8216; checkout-flow & # 8217;);
});Step-by-Step Setup for Performance Testing
npm init playwright @ latest
use: {
viewport: {width: 1280, height: 720},
deviceScaleFactor: 1,
timezoneId: & # 8216; UTC & # 8217;,
colorScheme: & # 8216; light-colored & # 8217;,
javaScriptEnabled: true,
ignoreHTTPSErrors: true,
}await page.addStyleTag ({
content: `
* {
transition: none! crucial;
animation: none! crucial;
}
`
});const context = await browser.newContext ({
recordHar: {path: & # 8216; network.har & # 8217;}
});await context.tracing.start ({
screenshots: true,
snapshots: true,
sources: true
});await context.tracing.stop ({path: & # 8216; trace.zip & # 8217;});const client = await page.context () .newCDPSession (page);
await client.send (& # 8216; Performance.enable & # 8217;);const navTiming = await page.evaluate (() = & gt;
performance.getEntriesByType (& # 8216; navigation & # 8217;)
);const resourcefulness = await page.evaluate (() = & gt;
performance.getEntriesByType (& # 8216; resource & # 8217;)
);npx playwright trial & # 8211; headed=false
await (navTiming [0] .domComplete) .toBeLessThan (3000);
Writing Your 1st Performance Test
test (& # 8216; page loads under 3s & # 8217;, async ({page}) = & gt; {
const start = Date.now ();
await page.goto (& # 8216; https: //example.com & # 8217;, {waitUntil: & # 8216; load & # 8217;});
expect (Date.now () & # 8211; start) .toBeLessThan (3000);
});tryout (& # 8216; sailing timing & # 8217;, async ({page}) = & gt; {
await page.goto (& # 8216; https: //example.com & # 8217;);
const n = performance.getEntriesByType (& # 8216; navigation & # 8217;) [0];
return {
dcl: n.domContentLoadedEventEnd & # 8211; n.startTime,
payload: n.loadEventEnd & # 8211; n.startTime
};
});
expect (data.load) .toBeLessThan (3000);
});test (& # 8216; hunting stream under 1.5s & # 8217;, async ({page}) = & gt; {
await page.goto (& # 8216; https: //example.com & # 8217;);
performance.mark (& # 8216; start & # 8217;);
// JS inside evaluate won & # 8217; t see Playwright actions,
// so marks only wrap DOM result.
homecoming null;
});
await page.click (& # 8216; # btn & # 8217;);
await page.waitForSelector (& # 8216; .results & # 8217;);
performance.mark (& # 8216; end & # 8217;);
performance.measure (& # 8216; flow & # 8217;, & # 8216; start & # 8217;, & # 8216; end & # 8217;);
return performance.getEntriesByName (& # 8216; feed & # 8217;) [0] .duration;
});
});test (& # 8216; CDP metrics & # 8217;, async ({page, browserName}) = & gt; {
if (browserName! == & # 8216; chromium & # 8217;) test.skip ();
const cdp = await page.context () .newCDPSession (page);
await cdp.send (& # 8216; Performance.enable & # 8217;);
await page.goto (& # 8216; https: //example.com & # 8217;);
console.log (await cdp.send (& # 8216; Performance.getMetrics & # 8217;));
});Analyzing Performance Results
Integrating Playwright Performance Tests Into CI/CD
Making Performance Testing Reliable
When Playwright Should Not Be Used for Performance Testing
Scale Your Playwright Performance Tests with BrowserStack Automate
Conclusion
Useful Resources for Playwright
Related Guides
Automate This With SUSA
Test Your App Autonomously