mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-20 18:11:27 -07:00
2.5 KiB
2.5 KiB
Browser Rendering Gotchas
Tier Limits
| Limit | Free | Paid |
|---|---|---|
| Daily browser time | 10 min | Unlimited* |
| Concurrent sessions | 3 | 30 |
| Requests/minute | 6 | 180 |
| Session keep-alive | 10 min max | 10 min max |
*Subject to fair-use policy.
Check quota:
const limits = await puppeteer.limits(env.MYBROWSER);
// { remaining: 540000, total: 600000, concurrent: 2 }
Always Close Browsers
const browser = await puppeteer.launch(env.MYBROWSER);
try {
const page = await browser.newPage();
await page.goto("https://example.com");
return new Response(await page.content());
} finally {
await browser.close(); // ALWAYS in finally
}
Workers vs REST: REST auto-closes after timeout. Workers must call close() or session stays open until keep_alive expires.
Optimize Concurrency
// ❌ 3 sessions (hits free tier limit)
const browser1 = await puppeteer.launch(env.MYBROWSER);
const browser2 = await puppeteer.launch(env.MYBROWSER);
// ✅ 1 session, multiple pages
const browser = await puppeteer.launch(env.MYBROWSER);
const page1 = await browser.newPage();
const page2 = await browser.newPage();
Common Errors
| Error | Cause | Fix |
|---|---|---|
| Session limit exceeded | Too many concurrent | Close unused browsers, use pages not browsers |
| Page navigation timeout | Slow page or networkidle on busy page |
Increase timeout, use waitUntil: "load" |
| Session not found | Expired session | Catch error, launch new session |
| Evaluation failed | DOM element missing | Use ?. optional chaining |
| Protocol error: Target closed | Page closed during operation | Await all ops before closing |
page.evaluate() Gotchas
// ❌ Outer scope not available
const selector = "h1";
await page.evaluate(() => document.querySelector(selector));
// ✅ Pass as argument
await page.evaluate((sel) => document.querySelector(sel)?.textContent, selector);
Performance
waitUntil options (fastest to slowest):
domcontentloaded- DOM readyload- load event (default)networkidle0- no network for 500ms
Block unnecessary resources:
await page.setRequestInterception(true);
page.on("request", (req) => {
if (["image", "stylesheet", "font"].includes(req.resourceType())) {
req.abort();
} else {
req.continue();
}
});
Session reuse: Cold start ~1-2s, warm connect ~100-200ms. Store sessionId in KV for reuse.