使用Express JS、Puppeteer和EJS生成PDF时遇TimeoutError求助
排查Express+Puppeteer+EJS PDF生成超时问题
核心排查方向
1. Puppeteer浏览器启动瓶颈
如果超时发生在浏览器启动阶段,大概率是环境资源不足或启动参数配置不合理:
- 调整启动参数,增加性能优化项:
const browser = await puppeteer.launch({ headless: 'new', // 新版无头模式稳定性更强 args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', // 解决Linux环境下/dev/shm空间不足问题 '--disable-gpu', '--disable-extensions', '--single-process' // 单进程模式减少资源占用 ], timeout: 60000 // 延长启动超时至60秒 });
2. EJS模板渲染阻塞
若超时出现在HTML生成阶段,需单独验证EJS渲染逻辑:
- 测试模板单独渲染,排查是否存在循环引用、异步未处理或数据量过大问题:
// 单独执行渲染测试 const testData = { /* 你的测试数据 */ }; try { const html = await ejs.renderFile('./views/pdf-template.ejs', testData); console.log('渲染完成,HTML长度:', html.length); } catch (err) { console.error('EJS渲染错误:', err); }
3. 页面资源加载卡住
Puppeteer默认等待networkidle2(网络空闲2秒),若页面存在外部资源加载失败/缓慢,会触发超时:
- 禁用不必要的资源加载,缩短等待条件:
const page = await browser.newPage(); // 拦截图片、样式、脚本等非必要资源 await page.setRequestInterception(true); page.on('request', (req) => { const blockedTypes = ['image', 'stylesheet', 'font', 'script']; blockedTypes.includes(req.resourceType()) ? req.abort() : req.continue(); }); // 仅等待DOM加载完成,而非网络完全空闲 await page.setContent(html, { waitUntil: 'domcontentloaded', timeout: 60000 });
环境与版本排查
- 核对
package.json中Puppeteer、Express、EJS版本,若近期有版本升级,尝试回退到之前可用的版本组合; - 检查系统资源:确保服务器/本地环境有足够内存(Puppeteer启动浏览器至少需要512MB以上空闲内存),CPU负载不超过80%;
- 验证Node.js版本:部分Puppeteer版本对Node.js版本有要求,比如v20+需搭配Puppeteer v21+。
错误栈定位
根据错误栈中TimeoutError的触发位置(如puppeteer.launch()、page.setContent()或page.pdf()),精准对应上述排查方向:
- 若在
launch():优先调整浏览器启动参数和系统资源; - 若在
setContent():检查EJS渲染结果和页面资源拦截; - 若在
pdf():尝试简化PDF生成参数(如去掉printBackground等耗性能选项)。
内容的提问来源于stack exchange,提问作者thedomguy
相关产品推荐
相关产品推荐

