Puppeteer Request Interception: Selective Loading Without Breaking Pages
Puppeteer request interception lets you block images, stylesheets, and fonts before they download. This blog shows a practical pattern for selective loading, with a script and verification steps for fidelity vs speed.
29 Jun 2026, 05:49 UTC

Problem: Unnecessary network load in Puppeteer automation
Puppeteer scripts that scrape web pages, run integration tests, or generate PDFs often download images, fonts, and tracking pixels before any application code executes. This inflates bandwidth consumption and can noticeably slow down automation workflows without contributing to the intended outcome. The practical takeaway is not to make Puppeteer faster in the abstract, but to make explicit decisions about what a page is allowed to load for a specific goal. Request interception provides the mechanism to make those decisions at the page level, but it must be applied thoughtfully because the consequences of blocking resources vary by site.
Interception by resource type
Puppeteer exposes request.resourceType() which returns values such as document, xhr, fetch, image, stylesheet, font, and media. Request interception hooks into the network pipeline before each request is sent, allowing the handler to choose abort, continue, redirect, or respond. In practice, engineers typically check the resource type and block categories that are unlikely to affect the functional outcome—such as images, stylesheets, and fonts—while keeping document, xhr, and fetch alive so the DOM and data requests can load. Blocking non-essential types reduces data transfer and can shorten time-to-first-content for functional checks, but the cost is reduced visual fidelity and any page logic that depends on the removed assets. Additionally, the interception handler runs synchronously in the event loop; long-running logic inside the stall navigation and can cause timeouts, so the handler should remain lightweight and avoid async work until after calling request.continue().
Browser contexts for isolation
Beyond resource control, Puppeteer provides browser contexts isolated storage for cookies, localStorage, and session data within a single browser instance. This supports parallel isolated tasks with lower overhead than launching multiple browser processes. Pages within the same context share the same viewport and can navigate independently, while contexts remain fully isolated from one another. This pattern is especially useful when the same automation needs to maintain separate authentication states or when testing scenarios that require clean storage between runs.
Worked example: selective loading script
Run this script with Node.js where Puppeteer is installed. Replace the placeholder URL with your target. The handler runs synchronously, so keep logic minimal and call request.continue() before performing any async operations.
const puppeteer = require('puppeteer');
const TARGET_URL = 'https://example.com';
const BLOCK_TYPES = new Set(['image', 'stylesheet', 'font', 'media']);
(async () => {
const browser = await puppeteer.launch({ headless: true });
const context = await browser.newContext();
const page = await context.newPage();
await page.setRequestInterception(true);
page.on('request', req => {
const type = req.resourceType();
if (BLOCK_TYPES.has(type)) {
req.abort();
} else {
req.continue();
}
});
await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });
// Verify functional content is present before proceeding
await page.waitForSelector('main', { timeout: 10000 }).catch(() => {});
await browser.close();
})();Expected checks: with interception enabled, you should observe fewer network requests for the blocked types. Run the same script with interception disabled and compare navigation timing and request counts to see the performance versus fidelity trade-off. Verify that key selectors such as main still appear in the DOM; blocking stylesheets can alter layout and break selectors that depend on rendered dimensions.
Trade-offs, limitations, and verification
Blocking resources can break page functionality, lazy loading, or anti-bot checks that expect full asset loads. Some sites compute layout from fonts or images and will render an incomplete DOM when those are aborted. API surface and default handling of resource types can change across major Puppeteer releases, so verify behavior against the version in use. Headless detection and site defenses evolve independently of Puppeteer, so interception alone is not a guarantee against blocking.
- Enable interception before the first navigation to avoid race conditions where early requests bypass the handler entirely.
- Keep the request handler small and synchronous; long-running logic can stall navigation and cause timeouts.
- Test a target page with and without blocking stylesheets and images to check whether target selectors remain present and page functionality stays intact.
A practical verification step is to open two browser contexts from one instance, set different cookies in each, and navigate to the same origin to confirm storage isolation. If functionality breaks, narrow the blocklist to only the resource types you truly dont need, or switch from a broad blocklist to a narrow allowlist for critical origins.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.