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

Puppeteer v19在GitHub Action中组件截图随机异常求助

Puppeteer v19在GitHub Action中批量截图随机渲染不完整问题解决

问题描述

本地环境用Puppeteer v19截图所有组件都正常,但在GitHub Action里循环截取30个组件时,会随机出现两种异常:

  • 组件没完全展开,高度比实际尺寸小
  • 组件元素没渲染全,比如该显示1、2、3,只截到1、2
    本质是截图时机太早,组件还没彻底渲染完。

当前使用的Puppeteer启动代码:

await puppeteer.launch({
  args: [
    '--disable-gpu',
    '--disable-gpu-compositing',
    '--disable-gpu-rasterization',
    '--single-process',
    '--ignore-certifacate-errors',
    '--start-maximized',
    '--no-sandbox',
    '--enable-features=NetworkService'
  ],
  defaultviewport: null,
  headless: true,
  isMobile: true
});

截图循环代码:

let components = await this.page.$$(selector);

for(const [index, component] of components.entries()) {
  try {
      await component.screenshot({path: filepath, captureBeyondViewport: false});
  } catch (e) {
  }
}

解决方案

1. 等组件渲染稳定再截图

截图前加等待逻辑,确保组件尺寸、内容彻底稳定。可以等组件高度不再变化,或者等特定动态元素加载出来:

for(const [index, component] of components.entries()) {
  try {
      // 等待组件高度稳定(两次测量高度一致)
      await this.page.waitForFunction((el) => {
        const firstHeight = el.offsetHeight;
        return new Promise(resolve => {
          setTimeout(() => {
            resolve(el.offsetHeight === firstHeight);
          }, 300);
        });
      }, {}, component);

      // 如果组件有动态加载的子元素,等它显示出来
      await component.waitForSelector('.dynamic-child', { timeout: 5000, visible: true });

      await component.screenshot({path: filepath, captureBeyondViewport: false});
  } catch (e) {
      console.error(`第${index}个组件截图失败:`, e);
  }
}

2. 调整Puppeteer启动参数

GitHub Action资源有限,当前参数可能限制了渲染能力,建议修改:

  • 删掉--single-process:单进程模式批量任务下容易资源不足,导致渲染滞后
  • 修正拼写错误--ignore-certifacate-errors为--ignore-certificate-errors
  • 把headless: true改成headless: "chrome":v19默认的新headless模式在部分场景稳定性不如旧模式
  • 添加--disable-dev-shm-usage:解决GitHub Action里共享内存不足的问题

调整后的启动代码:

await puppeteer.launch({
  args: [
    '--disable-gpu',
    '--disable-gpu-compositing',
    '--disable-gpu-rasterization',
    '--ignore-certificate-errors',
    '--start-maximized',
    '--no-sandbox',
    '--enable-features=NetworkService',
    '--disable-dev-shm-usage'
  ],
  defaultViewport: null,
  headless: "chrome",
  isMobile: true
});

3. 循环里加间隔,避免资源抢占

连续截图会让浏览器资源吃紧,每个组件截图前加短暂间隔,给浏览器留足渲染时间:

for(const [index, component] of components.entries()) {
  try {
      // 先确保组件已经渲染出高度
      await component.waitForFunction(el => el.offsetHeight > 0, {}, component);
      
      // 加500ms间隔,缓解资源压力
      await new Promise(resolve => setTimeout(resolve, 500));

      await component.screenshot({path: filepath, captureBeyondViewport: false});
  } catch (e) {
      console.error(`第${index}个组件截图失败:`, e);
  }
}

4. 先等页面全局资源加载完再拿组件列表

获取组件前,先等页面所有资源加载完成,避免组件还没初始化就开始截图:

// 等网络空闲(没有请求在进行)
await this.page.waitForLoadState('networkidle2');
// 或者等页面完全加载完成
// await this.page.waitForLoadState('load');

let components = await this.page.$$(selector);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:53:09