What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
waitUntil tells Puppeteer which navigation milestone to wait for—not whether a page is completely ready for every task. Use domcontentloaded or load when the next step depends on that browser event; use networkidle0 or networkidle2 only when their network-quiet thresholds suit the site. If your next action needs a particular element or application state, wait for that condition explicitly too.
What Puppeteer’s waitUntil option means
In Puppeteer, waitUntil selects the condition that must be met before a navigation-related operation resolves. The documented values are load, domcontentloaded, networkidle0 and networkidle2. The first two correspond to browser lifecycle events. The latter two require the number of active network connections to remain under a specified ceiling for at least 500 ms. The current API reference displayed Puppeteer version 25.12.0 when checked on September 29, 2026; consult the reference for the version you use if behavior or types have changed.
These milestones answer different questions. A browser event or a brief period of relative network quiet does not prove that a site has finished every asynchronous task, populated a particular component, or reached the state your script needs. Choose the least restrictive useful signal, then wait for the actual prerequisite of the next operation.
The four waitUntil values compared
| Value | Documented condition | What it is useful for | What it does not establish |
|---|---|---|---|
domcontentloaded |
Wait for the browser’s DOMContentLoaded event. |
The next step can start once the document has been parsed to this lifecycle milestone. | It does not establish that images, later scripts, or app-specific data are ready. |
load |
Wait for the browser’s load event. |
The next step needs the page’s load lifecycle event. | It is not a guarantee that every later request or application update has finished. |
networkidle0 |
No more than zero network connections for at least 500 ms. | A strict network-quiet threshold is a useful signal for the page. | It does not mean the app is correct, nor that every future request is finished. |
networkidle2 |
No more than two network connections for at least 500 ms. | Use when that less strict network-quiet threshold is a useful signal. | It does not guarantee a particular selector or application state is ready. |
The event and threshold definitions come from Puppeteer’s PuppeteerLifeCycleEvent reference. The key difference between the network-idle choices is the ceiling: networkidle0 permits zero connections, while networkidle2 permits up to two during the same minimum quiet interval.
Recommended Free Tools
#1 Best Overall
How to choose a value for the next step
Use domcontentloaded when document parsing is enough
If your script can proceed once the DOMContentLoaded event fires, this is the direct match. For example, you may then inspect document structure or begin waiting for a selector that appears after application code runs. Do not infer from the event alone that a dynamically rendered element already exists.
Use load when the load event is the requirement
Choose load when the work that follows specifically depends on the browser’s load event. It is a lifecycle condition, not a universal “fully ready” flag. A page may continue to make requests or update its interface after that event.
Use network idle only when the threshold matches the site
Consider networkidle0 when you need the stricter zero-connection interval and the site is expected to become that quiet. A page that keeps making requests can make this a poor fit. networkidle2 allows up to two connections for at least 500 ms, which can be a better signal when that allowance is appropriate—but it still does not tell you whether your target component has finished rendering.
Rank #2
Wait for the condition your task actually needs
If the next operation requires a particular button, result row, or application state, add an explicit wait for that target rather than treating a lifecycle event as a substitute. For instance, wait for a selector after navigation, then perform the action. This is practical guidance based on the lifecycle API’s defined scope: it reports navigation milestones and network thresholds, not the readiness of arbitrary application-specific state.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRunnable navigation examples
Install Puppeteer in a Node.js project with npm install puppeteer, then save this as navigate.js. It demonstrates a direct navigation, an explicit selector wait, response-status inspection, and cleanup:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
const response = await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 30000,
});
if (response && response.status() >= 400) {
throw new Error(`Navigation returned HTTP ${response.status()}`);
}
await page.waitForSelector('h1', { timeout: 10000 });
console.log(await page.title());
} finally {
await browser.close();
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Replace https://example.com and h1 with the destination and element your task needs. The example uses domcontentloaded because it then waits separately for the selector. To test another lifecycle condition, change only the waitUntil value to one of the four documented strings. Set a timeout that fits your own job; the example’s values are choices for this script, not Puppeteer defaults or guarantees about a site.
Rank #3
When an interaction triggers navigation
For a click that causes navigation, start waiting for navigation and clicking at the same time. If the click occurs before the wait is registered, the script can miss the navigation event. Puppeteer documents this pattern:
const [response] = await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('a.my-link'),
]);
if (response && response.status() >= 400) {
throw new Error(`Navigation returned HTTP ${response.status()}`);
}
The response check is optional if the HTTP status is irrelevant to the task. If the click is expected to update an element without navigating, use a wait for that element or state instead of waiting for navigation.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →goto() and waitForNavigation() details
page.goto(url, options) accepts navigation options including waitUntil and resolves to the main resource response. If there are multiple redirects, the response corresponds to the last redirect. Navigation to about:blank, or to the same URL with only a different hash, returns null. Therefore, check that a response exists before calling status().
Rank #4
Puppeteer’s Page.goto() reference also notes that in headless shell a valid HTTP error status such as 404 or 500 does not by itself cause goto() to throw. If the status matters, inspect HTTPResponse.status() rather than assuming a resolved navigation means a successful HTTP response. This status behavior is specifically documented for headless shell; do not generalize it beyond the stated context.
page.waitForNavigation(options) is intended for navigation triggered indirectly, such as by clicking a link. Its response can be null for a navigation to a different anchor or one caused by History API usage; History API URL changes count as navigation. See the Page.waitForNavigation() reference and the project’s Page API documentation for the documented navigation remarks.
Common problems and fixes
networkidle0never resolves: the page may not reach a stretch with zero active connections. Use a lifecycle event if that is sufficient, or choose a different readiness signal tied to the task. Do not switch blindly if the task truly depends on network quiet.networkidle2resolves but the target is missing: the threshold only measures connection count over the interval; wait explicitly for the selector or application state you need.- A click happened but the navigation wait timed out: the click may not have navigated, or the wait may have started too late. If navigation is expected, use the
Promise.allpattern above; if it is not, wait for the resulting UI change instead. response.status()causes an error:goto()orwaitForNavigation()can returnnullin documented cases. Guard the response before checking its status.- The script treats an HTTP error page as success: navigation completion and an acceptable HTTP status are separate checks in the documented headless-shell case. Inspect the response status and handle 4xx or 5xx responses according to your task.
- A wait times out despite a reachable site: the selected condition may not fit the site’s behavior, or the timeout may be too short for that run. Identify whether you need a browser event, a network threshold, or a specific element, then set the wait and timeout accordingly.
Or skip the browser setup
If the goal is a website screenshot rather than controlling a browser for a broader automation task, ScreenshotNeo offers a one-request screenshot API. Its API accepts a URL and returns PNG, JPEG or WebP output, or a PDF. The request below saves a WebP screenshot of Stripe; replace the target URL as needed. See the ScreenshotNeo API documentation for request options.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie and consent banners, newsletter popups and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and responses say which outcome occurred through X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for AI agents using Claude, Cursor or another MCP client. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.
Version and source notes
The definitions here reflect Puppeteer’s official lifecycle, navigation, and Page API references as checked on September 29, 2026. The API pages displayed version 25.12.0 at that time. The event and network-idle definitions are API behavior, not benchmark results; consult the linked references for the version you install.
Frequently Asked Questions
Does networkidle0 mean every request the page will ever make is finished?
No. It describes a zero-connection interval of at least 500 ms, not a promise that no later request or application update will occur.
Can I use more than one waitUntil value for one navigation?
The API accepts lifecycle conditions; check the type and options reference for the Puppeteer version in your project before relying on a particular combination.
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.

