What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use waitUntil in a navigation call to choose the browser lifecycle point at which that call may finish. Both Puppeteer and Playwright default to load, but their accepted values differ: Playwright supports commit, domcontentloaded, load and networkidle; Puppeteer supports domcontentloaded, load, networkidle0 and networkidle2. Choose the earliest boundary that lets your next operation work, then check the page’s actual content or state if that is what matters.
What waitUntil does
waitUntil tells a navigation method such as page.goto() how far the document’s loading lifecycle must progress before the navigation promise resolves. It is a boundary for navigation, not a general guarantee that an application has finished its own rendering, data fetching or background work.
In either library, the basic shape is:
await page.goto(url, { waitUntil: 'domcontentloaded' });
The value is passed in the navigation options. The examples below use JavaScript and the documented API names checked against the official references on September 29, 2026. Puppeteer’s references include both version 25.12.0 and a Next reference; check your installed package’s documentation when relying on version-sensitive details.
Which waitUntil value should you choose?
| Value | Framework | What it waits for | When it can fit |
|---|---|---|---|
commit |
Playwright only | The response has arrived and document loading has begun. | When you need navigation to start but do not need the document parsed or its load event fired yet. |
domcontentloaded |
Both | The document’s DOMContentLoaded event. |
When the next step needs the parsed document but need not wait for every resource associated with the load event. |
load |
Both; default in the cited references | The page’s load event. |
When the next operation specifically depends on that lifecycle event. |
networkidle |
Playwright only | No network connections for at least 500 ms. | Available as a lifecycle boundary, but Playwright discourages using it as a test-readiness signal. |
networkidle0 |
Puppeteer only | At most zero network connections for at least 500 ms. | When you specifically want Puppeteer’s zero-connection idle condition. |
networkidle2 |
Puppeteer only | At most two network connections for at least 500 ms. | When Puppeteer’s two-connection idle condition suits the page and task. |
Use commit when only the start of navigation matters
Playwright’s commit boundary is earlier than document parsing: it means the response was received and the document started loading. It is useful when the caller needs that navigation to begin but has no immediate need to inspect parsed content. Puppeteer’s documented lifecycle type has no corresponding value, so do not copy this literal into Puppeteer code.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches#1 Best Overall
Use domcontentloaded for an earlier document boundary
DOMContentLoaded indicates that the document has been parsed. It can let a script proceed before waiting for all resources associated with the page’s load event. It does not establish that a single-page application has fetched and displayed the particular data your task needs.
Use load only when the load event is the requirement
load is the default in both cited references. That makes it a reasonable choice when your next operation truly depends on the load event, but it is not automatically the fastest or most meaningful choice for every page. Set the option explicitly when the intended boundary should be clear to future readers of the code.
Treat network idle as a specific condition, not “ready”
Playwright defines networkidle as no network connections for at least 500 ms and explicitly advises against using that method for tests. Puppeteer’s networkidle0 and networkidle2 are separate lifecycle names, each using a 500 ms idle period. An idle network does not prove that the UI displays the correct result; conversely, a page with ongoing requests may never satisfy an idle condition. For tests, assert the outcome that matters instead.
Playwright: navigation examples
Set the boundary in page.goto() options. This example uses domcontentloaded, then waits for a meaningful locator rather than assuming the lifecycle event means app-specific work is complete.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
try {
const response = await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 30_000,
});
// Navigation can complete with an HTTP error response. Check status if needed.
console.log('HTTP status:', response?.status());
// Wait for the outcome this task needs, not merely a lifecycle boundary.
await page.getByRole('heading', { name: 'Example Domain' }).waitFor();
} finally {
await browser.close();
}
The timeout above is an explicit example setting, not a claim about Playwright’s default. In the cited Page API, goto documents a default of 0 ms; navigation and default timeout configuration can affect the effective behavior. Check the documentation for your installed Playwright version before depending on a default.
Wait for a load state after another navigation action
Playwright’s waitForLoadState() waits for the requested state after navigation has been committed. The Page documentation says it is usually unnecessary because Playwright auto-waits before actions. Prefer a locator or web-first assertion for a condition your test actually needs. If you do use a load state, apply it to the page that navigated:
await page.getByRole('link', { name: 'Products' }).click();
await page.waitForLoadState('domcontentloaded');
await page.getByRole('heading', { name: 'Products' }).waitFor();
Puppeteer: navigation examples
Puppeteer uses the same navigation-options shape for its supported lifecycle names. Its WaitForOptions reference also accepts an array of lifecycle events: all listed events must fire before the wait resolves.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
const response = await page.goto('https://example.com', {
waitUntil: ['domcontentloaded', 'networkidle2'],
timeout: 30_000,
});
console.log('HTTP status:', response?.status());
await page.waitForSelector('h1');
} finally {
await browser.close();
}
The array means “wait for both listed lifecycle events,” not “accept whichever happens first.” If you only need parsed markup, using domcontentloaded alone avoids making completion depend on the idle condition as well.
Recommended Free Tools
Rank #3
The cited Puppeteer Next WaitForOptions reference documents a 30,000 ms timeout default and says timeout: 0 disables the timeout. Defaults are version-sensitive; the explicit 30-second setting in the example makes its intent clear without relying on that default.
Navigation caused by a click
In Puppeteer, register the navigation wait before clicking. Starting the wait after the action risks missing a navigation that has already begun.
const [response] = await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('a.my-link'),
]);
console.log('Navigation response:', response?.status() ?? 'no response');
Puppeteer counts History API URL changes as navigation. An anchor navigation or History API navigation can resolve with a null response, so code should not assume that waitForNavigation() always returns an HTTP response.
Differences to remember when switching frameworks
- Network-idle spelling: Playwright uses
networkidle; Puppeteer usesnetworkidle0andnetworkidle2. - Earliest documented boundary: Playwright has
commit; the cited Puppeteer lifecycle type does not. - Multiple conditions: Puppeteer’s cited
WaitForOptionsaccepts an array and requires every listed event; the cited Playwright navigation option uses onewaitUntilvalue. - Timeout documentation: the cited Playwright
gotoreference documents a 0 ms default, while Puppeteer’s cited Next options reference documents 30,000 ms. These are framework- and reference-version-specific settings, not universal browser defaults.
Troubleshooting waitUntil problems
The navigation never reaches network idle
A continuing request can prevent the idle condition from occurring, and an idle condition may be unnecessary for the task. Choose an earlier boundary if the next step permits it, or wait for a specific locator or application condition. Do not use network quiet as a substitute for verifying rendered data.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
The option is rejected or behaves differently after a framework switch
Check the accepted literals for the library and installed version. In particular, do not use Playwright’s commit or networkidle names in Puppeteer, or Puppeteer’s networkidle0/networkidle2 names in Playwright.
The page reaches the selected event but the expected content is missing
The event only marks a navigation lifecycle boundary. Add a wait for a selector, locator or other observable state that represents the content your script needs. If the page returns a valid HTTP error status such as 404 or 500, Playwright’s goto() does not throw solely for that status; inspect the returned response status when it matters.
A click-triggered navigation wait times out
For Puppeteer, make sure waitForNavigation() is armed before the click, preferably together in Promise.all. Also check whether the click changes the page through a History API route and therefore produces a navigation without a conventional response.
The error is a timeout or navigation failure
Check the framework’s configured navigation or default timeout and the installed version’s documentation. Playwright documents failures for cases such as an invalid URL, navigation timeout, unreachable server, SSL failure or main-resource failure. A valid HTTP 404 or 500 response is different: inspect its status rather than treating it as a thrown navigation failure.
Best Value
Or skip the browser setup
If your goal is to obtain a website screenshot rather than control an automated browser navigation, ScreenshotNeo provides a screenshot API. Its request does not expose Puppeteer or Playwright’s waitUntil option, so use browser automation when that lifecycle control is required.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie and consent banners are accepted or removed before capture, along with supported newsletter popups and chat widgets; those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in headers. An MCP server provides screenshot tools for AI agents, and the Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up free for 1,000 screenshots a month, with no card required.
Frequently Asked Questions
Does waitUntil wait for JavaScript frameworks to finish rendering?
No. It waits for a navigation lifecycle boundary. Wait separately for the UI state your script needs.
Can I use networkidle as a screenshot readiness guarantee?
No. It describes network activity, not whether the image or content you expect has rendered.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




