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 matchPuppeteer navigation timeouts are reliable symptoms, not diagnoses. A page.goto() or page.waitForNavigation() timeout means the navigation wait did not observe its configured completion condition before the deadline. It does not necessarily mean the server was slow. First identify the rejecting method, then match the wait to what your workflow actually needs, register click waits before the click, and change a timeout only after confirming that the condition is correct and merely slow.
Identify which timeout is actually failing
Start by recording the complete error text, the exact line that rejects, your Puppeteer version, browser version, URL, call-level options, and page-level timeout configuration. Puppeteer uses separate timeout families, so changing a navigation timeout cannot fix an element wait or browser-launch failure.
| Rejecting operation | What it is waiting for | Relevant controls |
|---|---|---|
page.goto(), page.reload(), page.goBack(), page.goForward(), page.setContent(), or page.waitForNavigation() |
A navigation completion condition | Per-call timeout; page.setDefaultNavigationTimeout(); also affected by the general page default |
page.waitForSelector(), waitForResponse(), or waitForRequest() |
A selector, response, or request event | Per-call timeout or page.setDefaultTimeout() |
| Locator actions | Visibility, enabled state, and a stable bounding box before interaction | Page timeout by default; an individual locator timeout can be set |
puppeteer.launch() |
Browser startup | LaunchOptions.timeout, a separate launch setting |
The current Puppeteer API reference (version 25.12.0) documents a 30,000-millisecond default for wait options and a 30,000-millisecond browser-start default. A wait timeout of 0 disables that timeout. These are documented defaults, not measurements of your page’s performance.
Understand the timeout and wait scopes
Per-call options take priority
Set a timeout and completion event on the operation whose behavior you are diagnosing:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 45_000
});
The waitUntil default is 'load'. You can provide one lifecycle event or an array. The operation succeeds only when the selected condition occurs within the timeout.
Page-wide defaults
page.setDefaultNavigationTimeout(timeout) changes the default maximum for navigation methods, including goto, history navigation, reload, setContent, and waitForNavigation. page.setDefaultTimeout(timeout) sets the general page default used by selector, request, response, and other waits; it is also the inherited default for locator actions. Query the navigation value with page.getDefaultNavigationTimeout() while debugging.
page.setDefaultNavigationTimeout(45_000);
page.setDefaultTimeout(20_000);
console.log('navigation timeout:', page.getDefaultNavigationTimeout());
Keep these settings deliberate. A very large global value can make a genuine defect look like a hung test, while a small value can fail a healthy but variable page. Prefer a measured per-call override when only one route is slow.
Rank #2
Browser startup is different
const browser = await puppeteer.launch({ timeout: 60_000 });
This controls how long Puppeteer waits for the browser process to start. It does not extend a page navigation. Diagnose launch errors separately from page errors.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsPrevent the click/navigation race
If a click can trigger a document navigation, subscribe to navigation before dispatching the click. Waiting in two sequential statements can miss a fast navigation and leave waitForNavigation() waiting for an event that already happened.
const [response] = await Promise.all([
page.waitForNavigation({
waitUntil: 'domcontentloaded',
timeout: 30_000
}),
page.click('a.my-link')
]);
console.log('main-resource response:', response ? response.status() : 'none');
The promise array starts both operations immediately; the navigation listener is installed before the click runs. Use a locator for the action when appropriate, but keep the navigation wait in the same concurrency pattern:
const link = page.locator('a.my-link');
await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
link.click()
]);
Do not assume every URL change produces a response. Puppeteer treats History API URL changes as navigation, and anchor changes can also count, but waitForNavigation() resolves with null when there is no main-resource response.
Choose a completion signal that matches the application
Document navigation
Use domcontentloaded when the next action only needs the parsed document. Use load when the page’s load event is the required boundary. Neither event guarantees that a client-rendered dashboard is usable.
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.locator('#results').wait();
Network-idle conditions
Network-idle waits are appropriate only when network quiet is genuinely your readiness criterion. Applications with analytics, WebSockets, polling, streaming, or recurring fetches may never become quiet, so a network-idle timeout can be expected behavior rather than evidence of a broken navigation.
Rank #4
Single-page applications
For an SPA route change, wait for the state your next step consumes: an expected URL, a specific response, or a DOM element containing the result. A URL change alone does not prove that rendering or data loading is complete.
await page.click('button[data-route="reports"]');
await page.waitForFunction(
() => location.pathname === '/reports',
{ timeout: 30_000 }
);
await page.locator('[data-testid="report-table"]').wait();
If an API response is the meaningful boundary, subscribe before the action:
const [apiResponse] = await Promise.all([
page.waitForResponse(
response => response.url().endsWith('/api/reports') && response.ok()
),
page.click('#load-reports')
]);
console.log(await apiResponse.json());
For a selector, use waitForSelector or a locator wait rather than extending navigation indefinitely. These waits have their own timeout behavior and should describe the actual readiness requirement.
Best Value
- Used Book in Good Condition
Use a deterministic diagnostic workflow
- Capture the failure. Save the full
TimeoutError, rejecting method, URL, versions, and all explicit options. - Classify the wait. Decide whether it is browser startup, navigation, locator/action, selector, request, or response.
- Inspect scope. Search for per-call
timeoutandwaitUntil, then review every call tosetDefaultTimeoutandsetDefaultNavigationTimeout. LoggetDefaultNavigationTimeout(). - Remove races. Put click-triggered navigation or response waits in
Promise.all, with the wait first. - Define ready. Select a lifecycle event, URL, response, or DOM state based on the next operation—not habit.
- Log boundaries. Record timestamps before and after the action, the observed URL, response status when available, and whether the expected selector appeared.
- Reproduce consistently. Keep browser version, network conditions, authentication state, viewport, and page data the same while isolating the failure.
- Change one value. Increase a timeout only after the correct condition is observed regularly taking longer than the current limit.
Common failure patterns and fixes
| Symptom | Likely explanation | Fix |
|---|---|---|
waitForNavigation always times out after a button click |
The click updates SPA state or fires an API request instead of loading a document, or the listener was registered too late. | Register the wait before clicking; otherwise wait for the expected URL, response, or result element. |
Timeout occurs only with waitUntil: 'networkidle0' |
Background polling or persistent connections prevent the selected quiet condition. | Use a lifecycle event plus an application-specific readiness check. |
goto times out, but the page eventually appears |
The selected event takes longer than the deadline, or a subresource keeps the event from arriving. | Measure the event; use the earliest sufficient waitUntil and a targeted readiness wait. Increase the timeout only if that event is correct. |
| Changing navigation timeout has no effect on a selector failure | The rejecting call uses the general page timeout or its own option. | Set the selector/locator timeout or adjust setDefaultTimeout. |
| Browser launch fails before a page exists | The startup deadline is separate from page navigation. | Inspect launch arguments and process startup, then adjust launch({ timeout }) if startup is legitimately slow. |
Navigation returns null |
History API or anchor navigation changed the browsing state without a main-resource response. | Treat the URL or DOM state as the completion signal; do not require an HTTP response. |
Timeout design for reliable test suites
- Use the smallest condition that proves readiness. A document event followed by a result-element wait is usually clearer than an unbounded network-idle wait.
- Keep global defaults conservative and make exceptional routes explicit at the call site.
- Never use
timeout: 0as a blanket reliability fix. It disables the guard and can leave workers stuck forever; reserve it for a deliberately controlled operation with an external watchdog. - Separate navigation timing from application timing. A fast document can still have a slow API, and a slow document does not justify waiting for an API that never runs.
- Make logs identify the condition, not just the duration: “waiting for load,” “waiting for reports response,” and “waiting for report-table locator” lead to different fixes.
Or skip the browser setup
If your actual goal is a dependable screenshot rather than browser automation, ScreenshotNeo provides a single HTTP request. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture, and lets you turn each cleanup step off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with X-Page-Verdict and X-Billed headers explaining the result.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for options such as full-page lazy-image capture, CSS-selector element shots, device and retina settings, custom CSS or JavaScript, click and wait rules, request blocking, headers, cookies, geolocation, PDFs, caching, signed links, asynchronous webhooks, bulk capture, and the usage API. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.
FAQ
What is Puppeteer’s default navigation timeout?
The current API reference documents 30,000 milliseconds for wait options. A per-call setting or page default can override it, and 0 disables the timeout.
Should I always use networkidle0?
No. Use it only when network quiet is meaningful for the workflow. Polling and persistent connections can prevent it from completing.
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 →Why is waitForNavigation() returning null?
History API and anchor navigations can count as navigation without a main-resource response. Verify the URL or application state instead of expecting an HTTP response.
Frequently Asked Questions
Can I set different navigation and selector timeouts?
Yes. Use a per-call timeout for each wait, or configure navigation with setDefaultNavigationTimeout and general waits with setDefaultTimeout.
Does a locator solve navigation timing?
A locator waits for action preconditions such as visibility, enabled state, and a stable bounding box; it does not define when navigation or SPA rendering is complete.
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.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →




