Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Call and await dispose() when you are finished with a live Puppeteer handle: await handle.dispose();. This releases the referenced page object for garbage collection; it does not promise that memory is reclaimed immediately. ElementHandle uses the same method because it extends JSHandle.

Dispose of a handle after its last use

A JSHandle retains a reference to an object in the page context. For example, page.evaluateHandle() returns a handle rather than a plain JavaScript value. While that handle remains live, the referenced object is kept from garbage collection. Dispose of it as soon as your code no longer needs the reference.

const handle = await page.evaluateHandle(() => window);

// Use handle while needed.
await handle.dispose();

JSHandle.dispose() returns a Promise<void>, so use await to ensure the cleanup call completes before proceeding.

Dispose of an ElementHandle

An ElementHandle is a handle to a DOM element and inherits dispose() from JSHandle. Dispose it after its final operation. A finally block is useful when an operation might throw, because it still runs cleanup on the error path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const element = await page.waitForSelector('div.example');

try {
  if (element) {
    await element.click();
  }
} finally {
  await element?.dispose();
}

The null check matters: selector methods may return null when no element matches. Optional chaining in the cleanup also avoids calling dispose() on a null result.

Dispose of a selector handle after extracting data

If you pass a handle into page.evaluate() to read a value, dispose of the handle after the evaluation has finished. The evaluation result can be an ordinary string, while the handle remains a separate retained reference:

const bodyHandle = await page.$('body');

if (bodyHandle) {
  try {
    const html = await page.evaluate(body => body.innerHTML, bodyHandle);
    console.log(html);
  } finally {
    await bodyHandle.dispose();
  }
}

Know when Puppeteer disposes handles automatically

Puppeteer automatically disposes a handle when its associated frame navigates away or its parent execution context is destroyed. That lifecycle cleanup is not a substitute for disposing handles you are finished with while the context remains active—for example, during a long-running page session.

Disposal releases the reference for garbage collection; it does not guarantee immediate reclamation or a particular amount of memory freed. The API documentation does not establish that calling dispose() repeatedly is harmless, so structure code to dispose once, after the last use.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a locator or a value when you do not need a live handle

For ordinary element selection and interaction, Puppeteer’s current guide recommends locators. They are often a better fit than retaining an element handle just to click or fill an element. If you use the lower-level waitForSelector() API and keep its returned handle, dispose it when done.

For data extraction, consider an API that returns the value you need rather than a page-object reference. jsonValue() produces serializable portions as a plain value, but it is a separate operation: it is not documented as disposing of the originating handle. It can fail on circular structures and does not call toJSON.

Troubleshoot common handle-cleanup mistakes

  • Cleanup is skipped after an error: put the handle’s last operation in a try block and call dispose() in finally.
  • A selector result is null: check the result before using it. A missing match is not a handle, so it cannot be clicked or disposed as one.
  • You assumed extracting a value disposes the handle: it does not. Dispose the handle separately after the value operation completes.
  • You expected memory to drop immediately: disposal makes the referenced object eligible for garbage collection; it does not force collection or promise when it occurs.
  • You are keeping handles for routine interactions: use a locator when it suits the task, or return a serializable value when a live page-object reference is unnecessary.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

Disposing a Puppeteer handle is the right fix when your code needs to manage a retained page-object reference. If your actual goal is simply to capture a website screenshot, ScreenshotNeo is a separate screenshot API: one GET request returns an image or PDF without requiring you to manage a browser handle. It removes cookie banners, popups and chat widgets before capture; bot checks, blank pages and failed loads are not billed; and its MCP server lets AI agents take screenshots.

For example, this cURL request saves a WebP screenshot of Stripe:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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 documentation for request options. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

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.