Playwright-Lighthouse 报错“Has no properties”引发关注:自动化性能测试常见陷阱与应对

随着前端工程化对自动化性能测试的依赖日益加深,Playwright 与 Google Lighthouse 的组合成为众多开发团队的首选方案。然而近期,大量开发者在运行集成脚本时遭遇了令人困惑的报错信息——“Has no properties”或“Cannot read properties of undefined”,一时间在 GitHub Issue 和 Stack Overflow 上引发热议。这一错误究竟从何而来?又该如何破解?本文将为你展开深入剖析。

故障背景:当Playwright遇见Lighthouse

Playwright 是微软推出的浏览器自动化测试框架,以其跨浏览器、高稳定性著称;Lighthouse 则是 Google 官方开源的网页质量评估工具,可对页面性能、可访问性、SEO 等维度进行打分。通过社区封装库 playwright-lighthouse,开发者可以轻松在 Playwright 脚本中调用 Lighthouse 审计,实现“端到端 + 性能评估”的一体化流水线。

常见的用法是:

import { playwrightLighthouse } from 'playwright-lighthouse';
import { chromium } from 'playwright';

const browser = await chromium.launch({ args: ['--remote-debugging-port=9222'] });
const page = await browser.newPage();
await page.goto('https://example.com');
await playwrightLighthouse(page, { port: 9222, thresholds: { performance: 90 } });

然而,正是这套看似简洁的流程,近期却在不同操作系统和环境配置下频繁抛出异常,错误堆栈往往指向 playwright-lighthouse 内部调用 Lighthouse 核心模块时,某个对象或数组属性访问失败,最终报出 Has no properties

问题根源:端口、Chrome实例与协议版本的三方角力

根据多位维护者和资深开发者的排查,该错误的触发原因并非单一,而是多个因素叠加的结果:

  1. 调试端口未正确暴露
    Lighthouse 通过 Chrome DevTools Protocol(CDP)与浏览器通信。如果 Playwright 启动的浏览器实例没有正确开启 --remote-debugging-port,或端口号与 playwrightLighthouse 传入的 port 不一致,Lighthouse 将无法获取页面流,从而在内部构造 Runtime.evaluate 响应时遇到空值,最终抛出属性读取异常。

  2. Chromium 新版本与 Lighthouse 版本不兼容
    近期 Chrome 浏览器高频迭代,CDP 命令的参数结构有所调整。较旧版本的 Lighthouse(如 8.x)可能未适配新版 Chromium 的返回数据格式,导致某些字段缺失,进而出现“无属性”的连锁反应。

  3. 使用 headless 模式的坑
    部分开发者采用 chromium.launch({ headless: true }) 并同时开启调试端口。但 Playwright 的 headless 模式默认使用的 chromium 通道与 Lighthouse 期望的 --enable-automation 标志存在冲突,导致 Lighthouse 无法识别页面主线程,最终返回空结果对象。

  4. 异步时机问题
    如果 page.goto() 后立即调用 playwrightLighthouse,而页面尚未完成首次渲染,Lighthouse 在收集“加载性能”指标时可能拿到未定义的网络事件对象,也会触达该错误。

社区应对:官方修复与实战解法

目前,playwright-lighthouse 的维护者已在最新版本(3.0.0+)中提升了错误提示的清晰度,并优化了对现代 Chromium 的兼容性。但用户在遇到该问题时,仍可采取以下步骤快速排障:

  • 升级依赖:确保 playwright-lighthouseplaywrightlighthouse 均为最新版本。尤其要注意 peerDependencies 中的版本匹配,避免混用大版本。
  • 显式指定端口并确保唯一:在启动浏览器时不依赖默认端口,手动分配低冲突端口(如 9223),并检查系统是否已被占用。同时将 headless 设为 false 作为临时验证手段。
  • 延迟调用审计:在 page.goto() 之后,使用 page.waitForLoadState('networkidle') 等待稳定,再执行 Lighthouse 审计。
  • 绕行方案:如果要完全规避该错误,可放弃 Playwright 启动浏览器,改为直接通过 lighthouse CLI 生成报告,再与 Playwright 截图功能结合——尽管这牺牲了同步提取指标的便利性。

展望:性能测试基础设施仍需“细颗粒度”维护

本次报错事件虽然表象是“一个异常”,其背后却反映了现代 web 工具链的脆弱性:浏览器版本每六周更新一次,Lighthouse 逐步迭代审计规则,而中间层封装库一旦维护滞后,就会引发连锁故障。对于开发者而言,尤其是依赖自动化性能预算的 CI/CD 团队,建议在流水线中固定 Browser 与 Lighthouse 的主版本号,而不是盲目使用 latest。同时,时刻关注上游 release note,做到“先监控、再升级”。

总的来看,“Playwright-Lighthouse Has no properties Error”并非不可逾越的鸿沟。通过合理的版本锁定、配置校验和异步等待,团队完全可以重建稳定可靠的前端性能回归防线。而这一小插曲,也再次提醒我们:自动化测试的每一环,都值得被认真对待。