You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Firebase云函数生成动态页面PDF内容不全问题

解决Firebase Functions中Puppeteer生成PDF内容截断问题

针对本地能生成完整150页PDF、线上Firebase环境仅生成30/50页的问题,从页面加载、Puppeteer配置、函数资源三个方向给出解决方案:

1. 修复页面内容加载不完整问题

线上环境网络和渲染速度比本地慢,当前的等待逻辑可能没覆盖所有异步内容加载:

  • 处理懒加载内容:如果页面单元内容是滚动加载,Puppeteer默认不会触发滚动,导致下方内容未渲染。添加滚动逻辑:
// 在waitForSelector('div.content-has-loaded')之后添加
await page.evaluate(async () => {
  await new Promise((resolve) => {
    let totalHeight = 0;
    const distance = 1000;
    const timer = setInterval(() => {
      const scrollHeight = document.body.scrollHeight;
      window.scrollBy(0, distance);
      totalHeight += distance;
      if (totalHeight >= scrollHeight) {
        clearInterval(timer);
        resolve();
      }
    }, 200);
  });
});
// 滚动后等待内容渲染
await delay(1000);
  • 强化等待逻辑:将waitUntil: "networkidle2"改为waitUntil: "networkidle0",确保所有网络请求完成;同时增加对图片加载完成的检查:
await page.waitForFunction(() => {
  const imgs = document.querySelectorAll('img');
  return Array.from(imgs).every(img => img.complete);
});

2. 优化Puppeteer启动参数

Firebase Functions的容器环境有资源限制,调整启动参数避免渲染异常:

const browser = await puppeteer.launch({
  args: [
    "--no-sandbox",
    "--disable-dev-shm-usage", // 解决容器/dev/shm空间不足问题
    "--disable-gpu",
    "--disable-setuid-sandbox",
    "--window-size=1920,1080" // 设置固定视口,避免自适应布局导致内容截断
  ],
  headless: 'new', // 使用新版无头模式,渲染更稳定
});

3. 验证函数资源与超时配置

  • 确认timeoutSeconds: 120是否足够:生成150页PDF需要较长时间,可尝试调整到300秒(Firebase Functions最大超时)
  • 检查函数日志:在Firebase控制台查看函数执行日志,确认是否有内存不足、超时或渲染报错信息,若有内存警告可尝试申请更高内存配额(最大8GB)

4. 调试线上渲染状态

在生成PDF前添加全屏截图,验证页面是否完整渲染:

// 在page.pdf()之前添加
const screenshot = await page.screenshot({ fullPage: true });
// 将截图上传到Firebase Storage查看
await admin.storage().bucket().file(`debug/${courseID}-${sectionID}.png`).save(screenshot);

修改后的核心代码片段

// ... 原有代码 ...

const browser = await puppeteer.launch({
  args: [
    "--no-sandbox",
    "--disable-dev-shm-usage",
    "--disable-gpu",
    "--disable-setuid-sandbox",
    "--window-size=1920,1080"
  ],
  headless: 'new',
});

let page = await browser.newPage();

await page.goto(url, { waitUntil: "networkidle0" });
await page.waitForSelector('div.section-pdf-container')
await page.waitForSelector('#section-title')
await page.waitForSelector('div.content-has-loaded')

// 处理懒加载内容
await page.evaluate(async () => {
  await new Promise((resolve) => {
    let totalHeight = 0;
    const distance = 1000;
    const timer = setInterval(() => {
      const scrollHeight = document.body.scrollHeight;
      window.scrollBy(0, distance);
      totalHeight += distance;
      if (totalHeight >= scrollHeight) {
        clearInterval(timer);
        resolve();
      }
    }, 200);
  });
});
await delay(1500); // 等待渲染完成

// 等待所有图片加载
await page.waitForFunction(() => {
  const imgs = document.querySelectorAll('img');
  return Array.from(imgs).every(img => img.complete);
});

const pdf = await page.pdf({
  displayHeaderFooter: true,
  headerTemplate: '<style>html { -webkit-print-color-adjust: exact;}</style><div style="font-size: 9px; color:rgba(0,0,0,.35); padding-left: 30px;">The Journey: ' + unitTitle + '</div>',
  footerTemplate: '<style>html { -webkit-print-color-adjust: exact;}</style><div style="font-size: 9px; color:rgba(0,0,0,.35); padding-right: 30px; width:100%; text-align:right;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
  printBackground: true,
  margin: { top: '0.5in', bottom: '0.5in', left: '0.3in', right: '0.3in' }
});

// ... 原有代码 ...

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:10:35