无头截图截到空白画布:时机、DPR 和窗口尺寸的三重坑
一、空白不是渲染失败
页面在真实浏览器里正常,无头模式截出来一片纯黑,最容易误判成 WebGL 不可用或 Canvas 尺寸为 0。实际上多数情况是截图早于绘制:无头模式加载极快,--screenshot 在首帧动画完成前就取图了。
加 --virtual-time-budget=6000 让虚拟时间快进几秒,等动画推进几帧再截,问题立刻消失。这个参数比 sleep 可靠,因为它不依赖墙钟。
二、窗口尺寸必须显式给
默认视口是 800×600,和实际投放的 1280×720 差很远。Canvas 常见写法是按 window.innerWidth 适配,视口不对,构图就变形,甚至把主体裁掉。
正确姿势是 --window-size=1280,720,同时页面里用 devicePixelRatio 适配高分屏。注意 headless 的 DPR 默认是 1,想要 2 倍图得显式设 --force-device-scale-factor=2,否则截出来是 1280×720 的低清图。
三、截图与页面自适应的顺序
如果页面在 resize 时才重绘,那么窗口尺寸必须在加载前设定,否则会先按默认尺寸画一帧、再收到 resize 事件、再画一帧,截到的可能是中间态。
稳妥做法是在页面里监听 resize 并做防抖重绘,截图端给足虚拟时间。两边都做,才不会偶发。
四、临时服务的生命周期
截图需要起一个本地静态服务(python -m http.server 就够)。两个细节:端口要可配,8099 被占就直接换;进程要及时回收,否则下次启动报端口占用,看起来像代码 bug。
还要等服务真正就绪再截:轮询 127.0.0.1 直到返回 200,比固定 sleep 靠谱得多。轮询 20 次、每次 300 毫秒,覆盖绝大多数冷启动。
五、结果校验
截完不要只看文件存在,要校验尺寸:读图确认宽高等于目标值,再抽几个像素确认不是纯色。这两条断言能挡掉 90% 的「截到了但没用」的情况。
- 点赞
- 收藏
- 关注作者
评论(0)