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

如何在Cypress中使用PerformanceObserver?当前无法触发回调

在Cypress中使用PerformanceObserver捕获Longtask的解决方案

你的Cypress代码无法触发PerformanceObserver回调,主要是注册时机过晚、缺少等待逻辑和作用域问题导致的,以下是修正后的实现方案,和你Playwright的逻辑保持一致:

方案一:提前注册Observer(推荐)

利用cy.visit的onBeforeLoad钩子,在页面加载前就注册PerformanceObserver,确保不会错过初始化阶段的longtask:

cy.visit('你的目标网站URL', {
  onBeforeLoad(win) {
    // 挂载到window对象,避免作用域丢失
    win.__totalBlockingTime = 0;
    const observer = new win.PerformanceObserver((list) => {
      const entries = list.getEntries();
      entries.forEach(entry => {
        if (entry.entryType === 'longtask') {
          // 按照标准TBT计算规则,累加超过50ms的部分
          win.__totalBlockingTime += Math.max(entry.duration - 50, 0);
        }
      });
    });
    observer.observe({ entryTypes: ['longtask'], buffered: true });
  }
})
// 等待足够时间确保所有longtask被捕获,可根据页面情况调整时长
.wait(5000)
.window()
.then(win => {
  const totalBlockingTime = win.__totalBlockingTime;
  console.log('总阻塞时间(TBT):', totalBlockingTime);
  // 可添加断言逻辑
  expect(totalBlockingTime).to.be.a('number');
});

方案二:用Promise包裹等待逻辑

和Playwright的实现逻辑更接近,在cy.window()中返回Promise,让Cypress自动等待结果:

cy.window().then(win => {
  return new Promise(resolve => {
    let totalBlockingTime = 0;
    const observer = new win.PerformanceObserver((list) => {
      const entries = list.getEntries();
      entries.forEach(entry => {
        if (entry.entryType === 'longtask') {
          totalBlockingTime += Math.max(entry.duration - 50, 0);
        }
      });
    });
    observer.observe({ entryTypes: ['longtask'], buffered: true });

    // 超时后返回结果并断开观察者
    setTimeout(() => {
      observer.disconnect();
      resolve(totalBlockingTime);
    }, 5000);
  });
}).then(totalBlockingTime => {
  console.log('总阻塞时间(TBT):', totalBlockingTime);
  // 断言或其他处理
});

原代码失效的核心原因

  1. 注册时机滞后:如果在cy.visit完成后才注册Observer,页面加载过程中产生的longtask已经触发,buffered: true可能无法回溯捕获(受浏览器实现和Cypress页面加载流程影响)。
  2. 缺少等待机制:Cypress是异步命令队列,原代码注册完Observer后没有等待回调触发或超时,导致无法获取到计算结果。
  3. 作用域问题:外部变量totalBlockingTime在Cypress异步回调中被修改,但后续没有代码读取该值,且Cypress的作用域隔离可能导致值无法正确捕获。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:46:30