几种简陋的页面卡顿检测方法,但还是有点用

Web Worker 心跳方案

Web Worker 提供了一种将一些任务放在后台线程中执行的能力,从而避免阻塞主线程。利用 Web Worker,我们可以创建一个心跳检测机制:在 Web Worker 中不断发送心跳信号到主线程,主线程接收到信号后回复。通过比较发送和接收的时间差,我们可以监测出主线程的卡顿情况。

js 复制代码
// 主线程
const worker = new Worker("worker.js");
let lastPong = Date.now();

worker.postMessage("ping");

worker.onmessage = function (event) {
  if (event.data === "pong") {
    const currentPong = Date.now();
    const diff = currentPong - lastPong;

    if (diff > 100) {
      // 假设100ms为卡顿阈值
      console.log("主线程卡顿", diff + "ms");
    }

    lastPong = currentPong;
    setTimeout(() => worker.postMessage("ping"), 1000); // 每秒发送一次心跳
  }
};

// worker.js
onmessage = function (event) {
  if (event.data === "ping") {
    postMessage("pong");
  }
};

优点

  • 不阻塞主线程,可以在后台不断检测。
  • 实现简单,容易理解。

缺点

  • 线程通信耗时,可能导致误报。
  • JavaScript 的计时器并不十分精确,尤其在各种浏览器中表现不一,这也增加了不确定性。

window.requestAnimationFrame 方案

window.requestAnimationFrame 是浏览器提供的用于在下一次重绘之前更新动画的方法。它调用的频率通常和浏览器的重绘频率一致,大约是 60 次/秒。我们可以利用这个 API 来检测两次执行间隔时间,如果间隔明显超过 16.7ms(1000ms/60),则可以认为发生了卡顿。

js 复制代码
let lastFrame = performance.now();

function checkFrame() {
  const currentFrame = performance.now();
  const diff = currentFrame - lastFrame;

  if (diff > 50) {
    // 假设超过50ms为卡顿
    console.log("页面卡顿", diff + "ms");
  }

  lastFrame = currentFrame;
  requestAnimationFrame(checkFrame);
}

requestAnimationFrame(checkFrame);

优点

  • 与浏览器重绘同步,较为精确地反映了渲染性能。
  • API 简单易用。

缺点

  • 只能检测渲染相关的卡顿,对于事件处理等其他类型的卡顿检测不全面。
  • 用户实际感受到的卡顿可能包括事件延迟、大的布局偏移等,该方案无法完全覆盖。

PerformanceObserver 方案

PerformanceObserver API 允许我们监测和收集性能相关的数据。我们可以利用它来观察如 longtask(长任务)、layout-shift(布局偏移)和耗时的事件处理等性能问题。

js 复制代码
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === "longtask") {
      console.log("长任务", entry.duration + "ms");
    } else if (entry.entryType === "layout-shift" && !entry.hadRecentInput) {
      console.log("布局偏移,分数:", entry.value);
    } else if (entry.entryType === "event" && entry.duration > 50) {
      console.log("耗时事件", entry.duration + "ms");
    }
  }
});

observer.observe({
  type: ["longtask", "layout-shift", "event"],
  buffered: true,
});
  • longtask: 是指那些执行时间超过50毫秒的任务,它们可能会导致UI卡顿。
  • layout-shift: 是指页面布局发生变化的情况,如果没有由于用户输入而发生的布局变化,并且变化很大,那么它可能会影响用户体验。
  • event: 代表事件处理的耗时,如果处理时间过长,会导致用户感觉到卡顿。

优点

  • 提供了更全面的性能数据。
  • 可以实时监测多种类型的性能问题。

缺点

  • 需要考虑 API 兼容性。
  • 需要根据具体业务的性能指标调整阈值,如 layout-shift 的 value 阈值。

最后

监测 Web 页面卡顿是确保良好用户体验的关键步骤。我们可以通过 Web Worker 心跳方案、window.requestAnimationFrame方案和PerformanceObserver方案来检测不同类型的卡顿。每种方案都有其适用场景和局限性。为了更全面地监控页面性能,通常需要结合使用这些方法,并且不断调整和优化检测策略。

相关推荐
疯子****19 分钟前
【无标题】
前端·clawdbot
RichardLau_Cx43 分钟前
【保姆级实操】MediaPipe SDK/API 前端项目接入指南(Web版,可直接复制代码)
前端·vue·react·webassembly·mediapipe·手部追踪·前端计算机视觉
不爱写程序的东方不败1 小时前
APP接口测试流程实战Posman+Fiddler
前端·测试工具·fiddler
晚霞的不甘2 小时前
Flutter for OpenHarmony构建全功能视差侧滑菜单系统:从动效设计到多页面导航的完整实践
前端·学习·flutter·microsoft·前端框架·交互
黎子越2 小时前
python相关练习
java·前端·python
北极糊的狐2 小时前
若依项目vue前端启动键入npm run dev 报错:不是内部或外部命令,也不是可运行的程序或批处理文件。
前端·javascript·vue.js
XRJ040618xrj2 小时前
Nginx下构建PC站点
服务器·前端·nginx
We་ct2 小时前
LeetCode 289. 生命游戏:题解+优化,从基础到原地最优
前端·算法·leetcode·矩阵·typescript
有诺千金3 小时前
VUE3入门很简单(4)---组件通信(props)
前端·javascript·vue.js
2501_944711433 小时前
Vue-路由懒加载与组件懒加载
前端·javascript·vue.js