npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fps-auto-report

v1.5.1

Published

A npm package for FPS monitoring and performance reporting with web-vitals integration

Downloads

39

Readme

fps-auto-report

一个用于监控帧率(FPS)和性能指标并自动上报的 npm 包,集成了 Google 官方的 web-vitals 库。

功能特性

  • FPS 统计:实时监控页面帧率,提供平均、最小、最大 FPS 数据
  • Web Vitals 集成:自动收集 CLS、FCP、LCP、TTFB、INP 等性能指标(基于 web-vitals 5.x)
  • 组件曝光追踪:支持追踪组件出现在视口的次数,避免滚动误报
    • 延迟确认机制(默认500ms),确保数据准确性
    • 高性能架构:复用 Observer 实例,使用 WeakMap 自动 GC
    • 支持多种追踪方式:选择器、DOM元素、自定义ID
    • 支持4种上报时机:立即上报、手动上报、批量上报、定时上报
  • 混合上报策略:FPS、Web Vitals 和 Exposure 独立上报,互不耦合
    • FPS:支持基于卡顿等级的智能上报或固定间隔上报
    • Web Vitals:支持事件驱动上报(指标变化时)或固定间隔上报
    • Exposure:支持事件驱动或定时上报
  • 增强的上报层(v1.5.0):提供采样控制、批量传输、离线缓存、失败重试等高级功能
    • 采样控制:按页面路径动态采样率配置,减少数据量
    • 批量上报:防抖批量上报,减少网络请求
    • 离线缓存:localStorage 缓存失败数据,网络恢复后自动上报
    • 失败重试:指数退避策略,确保数据可靠传输
  • 性能标记工具(v1.5.0):提供手动埋点功能,追踪业务关键节点性能
    • 支持 mark()measure() 方法
    • 自动计算耗时并上报
    • 支持业务上下文关联(userId、goodsId 等)
  • 框架集成(v1.5.0):提供 React Hook 和 Vue Router 集成支持
    • React Hook:useComponentPerf 自动追踪组件挂载耗时
    • Vue Router:自动追踪路由切换耗时(Vue 2/3 支持)
  • Babel 插件(v1.5.0):自动为异步函数插入性能追踪代码,构建时自动插桩
    • 支持函数名模式匹配(include/exclude)
    • 支持多种函数类型:函数声明、函数表达式、箭头函数、类方法
    • 追踪代码自动用 try-catch 包裹,避免影响主逻辑
  • 页面信息收集:自动收集 URL、标题、视口大小等页面信息,支持自定义扩展
  • 可配置上报:支持自定义上报接口和上报方式,避免内置上传接口
  • 灵活使用:可作为第三方包在不同项目中使用
  • TypeScript 支持:完整的 TypeScript 类型定义

安装

npm install fps-auto-report web-vitals

yarn add fps-auto-report web-vitals

pnpm add fps-auto-report web-vitals

使用方法

基础用法

import { createFPSReporter } from 'fps-auto-report';

// 创建上报器实例
const reporter = createFPSReporter({
  reportUrl: 'https://your-api.com/report',
  reportMethod: 'POST'
});

// 开始监控和上报
reporter.start();

完整配置示例

import { createFPSReporter } from 'fps-auto-report';

const reporter = createFPSReporter({
  // 必填:上报接口地址(如果使用自定义上报函数则可不填)
  reportUrl: 'https://your-api.com/report',
  
  // 可选:上报方法,默认 POST
  reportMethod: 'POST', // 'POST' | 'GET' | 'PUT' | 'PATCH'
  
  // 可选:自定义上报函数(优先级高于 reportUrl)
  customReporter: async (data) => {
    // 自定义上报逻辑
    await fetch('https://your-api.com/custom-report', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
  },
  
  // 可选:FPS 统计间隔(毫秒),默认 1000
  fpsInterval: 1000,
  
  // 可选:是否启用 web-vitals 统计,默认 true
  enableWebVitals: true,
  
  // 可选:是否自动上报,默认 true
  autoReport: true,
  
  // 可选:上报间隔(毫秒),默认 5000
  reportInterval: 5000,
  
  // 可选:是否在页面卸载时上报,默认 true
  reportOnUnload: true,
  
  // 可选:自定义页面信息收集函数
  collectPageInfo: () => {
    return {
      url: window.location.href,
      title: document.title,
      customField: 'custom value',
      // 可以添加任意自定义字段
    };
  },
  
  // 可选:请求头配置
  headers: {
    'Authorization': 'Bearer token',
    'X-Custom-Header': 'value'
  },
  
  // 可选:是否启用调试模式,默认 false
  debug: true,
  
  // 可选:日志模式,在此模式下所有上报都只打印日志,不进行真实上报
  // 适用于测试阶段,避免接口上报出现问题,默认 false
  logOnly: false,
  
  // ========== 混合上报策略配置(推荐) ==========
  
  // FPS 上报策略
  fpsReportStrategy: {
    enabled: true,              // 是否启用 FPS 上报,默认 true
    levelBased: true,           // 是否启用基于等级的智能上报,默认 true
    interval: 5000,             // 固定上报间隔(当 levelBased 为 false 时使用)
    levelThresholds: {          // FPS 等级阈值
      excellent: 55,
      good: 45,
      fair: 30,
      poor: 20
    },
    levelStrategy: {            // 各等级上报间隔(毫秒)
      excellent: 30000,         // 优秀:30秒
      good: 5000,               // 良好:5秒
      fair: 5000,               // 一般:5秒
      poor: 2000,               // 较差:2秒
      severe: 1000              // 严重:1秒
    }
  },
  
  // Web Vitals 上报策略
  webVitalsReportStrategy: {
    enabled: true,              // 是否启用 Web Vitals 上报,默认 true
    reportOnChange: true,       // 指标变化时立即上报(推荐),默认 true
    reportOnFirst: true,        // 指标首次出现时上报,默认 true
    reportInterval: 5000       // 固定上报间隔(当 reportOnChange 为 false 时使用)
  }
});

// 开始监控
reporter.start();

混合上报策略示例

import { createFPSReporter } from 'fps-auto-report';

const reporter = createFPSReporter({
  reportUrl: 'https://your-api.com/report',
  
  // FPS 按等级智能上报
  fpsReportStrategy: {
    enabled: true,
    levelBased: true,
    levelThresholds: { excellent: 55, good: 45, fair: 30, poor: 20 },
    levelStrategy: {
      excellent: 30000,  // 优秀时降低上报频率
      good: 5000,
      fair: 5000,
      poor: 2000,        // 较差时提高上报频率
      severe: 1000       // 严重时高频上报
    }
  },
  
  // Web Vitals 事件驱动上报
  webVitalsReportStrategy: {
    enabled: true,
    reportOnChange: true,   // 指标变化时立即上报
    reportOnFirst: true     // 首次出现时上报
  }
});

reporter.start();

手动上报

// 上报所有数据(FPS + Web Vitals)
await reporter.report();
// 或
await reporter.reportAll();

// 仅上报 FPS 数据
await reporter.reportFPS();

// 仅上报 Web Vitals 数据
await reporter.reportWebVitals();

// 仅上报曝光数据
await reporter.reportExposure('element-id');  // 上报特定元素
await reporter.reportExposure();              // 上报所有元素

// 获取当前 FPS 数据
const fpsData = reporter.getFPSData();
console.log('Current FPS:', fpsData.fps);
console.log('FPS Level:', fpsData.level);
console.log('Average FPS:', fpsData.averageFPS);

// 获取 web-vitals 指标
const metrics = reporter.getWebVitalsMetrics();
console.log('Web Vitals:', metrics);

// 获取曝光追踪器
const exposureTracker = reporter.getExposureTracker();

// 追踪元素
const elementId = exposureTracker.track('#my-component', 'component-1');

// 获取曝光数据
const exposureData = exposureTracker.getExposureData('component-1');
console.log('Exposure count:', exposureData?.exposureCount);

// 重置统计数据
reporter.reset();

// 停止监控
reporter.stop();

使用类方式

import FPSReporter from 'fps-auto-report';

const reporter = new FPSReporter({
  reportUrl: 'https://your-api.com/report'
});

reporter.start();

组件曝光追踪示例

import { createFPSReporter } from 'fps-auto-report';

const reporter = createFPSReporter({
  reportUrl: 'https://your-api.com/report'
});

// 获取曝光追踪器
const tracker = reporter.getExposureTracker();

// 方式1: 通过选择器追踪
tracker.track('#ad-banner', 'ad-1');

// 方式2: 通过 DOM 元素追踪
const element = document.querySelector('.product-card');
if (element) {
  tracker.track(element, 'product-1');
}

// 开始监控
reporter.start();

// 立即上报(事件驱动)
import { ExposureTracker } from 'fps-auto-report';

const immediateTracker = new ExposureTracker({
  reportOnExposure: true,
  onExposure: async (event) => {
    await fetch('/api/exposure', {
      method: 'POST',
      body: JSON.stringify(event)
    });
  }
});

// 手动上报
await reporter.reportExposure('ad-1');  // 上报特定元素
await reporter.reportExposure();        // 上报所有元素

// 批量上报(与其他数据一起)
await reporter.reportAll();  // 包含 FPS + Web Vitals + Exposure

// 定时上报
setInterval(async () => {
  await reporter.reportExposure();
}, 30000);  // 每 30 秒上报一次

更多曝光追踪功能的使用方法,请参考 组件曝光监控使用指南

日志模式(测试阶段)

在测试阶段,可以使用日志模式来避免接口上报出现问题。在此模式下,所有上报都只打印日志,不进行真实的上报。

import { createFPSReporter } from 'fps-auto-report';

const reporter = createFPSReporter({
  reportUrl: 'https://your-api.com/report',
  
  // 启用日志模式(测试阶段)
  logOnly: true,  // 所有上报都只打印日志,不进行真实上报
  
  debug: true     // 建议同时启用调试模式,查看详细日志
});

reporter.start();

日志模式输出示例:

[FPS Reporter] [LOG ONLY MODE] Would report data: {
  "fps": { ... },
  "pageInfo": { ... },
  "timestamp": 1234567890
}
[FPS Reporter] [LOG ONLY MODE] Report URL: https://your-api.com/report
[FPS Reporter] [LOG ONLY MODE] Report Method: POST

增强的上报层(批量上报、采样控制、离线缓存)

v1.5.0 新增的增强上报功能,提供更可靠和高效的数据上报机制。

import { createFPSReporter } from 'fps-auto-report';

const reporter = createFPSReporter({
  reportUrl: 'https://your-api.com/report',
  
  // 启用批量上报模式
  useBatchReport: true,
  
  // MetricReporter 配置
  metricReporterConfig: {
    // 采样控制:按页面路径配置采样率
    sampleRateMap: {
      '/': 1,              // 首页100%采样
      '/goods/detail': 0.8, // 商品详情页80%采样
      '/cart': 0.5,        // 购物车50%采样
      default: 0.3         // 其他页面30%采样
    },
    
    // 批量上报配置
    maxQueueSize: 50,           // 最大队列大小
    batchDebounceDelay: 500,   // 防抖延迟(毫秒)
    
    // 离线缓存配置
    enableOfflineCache: true,   // 启用离线缓存
    maxCacheSize: 100,          // 最大缓存条数
    
    // 失败重试配置
    enableRetry: true,          // 启用重试
    retryConfig: {
      maxCount: 3,              // 最大重试次数
      initialDelay: 1000,        // 初始延迟(毫秒)
      exponentialBackoff: true  // 指数退避
    }
  }
});

reporter.start();

📖 详细文档

性能标记工具(手动埋点)

v1.5.0 新增的手动埋点功能,用于追踪业务关键节点性能。

import { mark, measure } from 'fps-auto-report';

// 标记开始
const startMark = mark('checkout:start', { 
  userId: '123',
  orderId: '456'
});

// ... 执行业务逻辑

// 标记结束并计算耗时
const endMark = mark('checkout:end', { 
  userId: '123',
  orderId: '456'
});

// 计算耗时(自动上报)
const duration = measure(
  'checkout:duration',
  startMark,
  endMark,
  { userId: '123', orderId: '456' }
);

console.log(`结账耗时: ${duration}ms`);

📖 详细文档

React Hook 集成

v1.5.0 新增的 React Hook,自动追踪组件挂载耗时。

import { useComponentPerf } from 'fps-auto-report';

// 自动追踪组件挂载耗时
const MyComponent = () => {
  useComponentPerf('MyComponent', { 
    userId: '123',
    pageType: 'product'
  });
  
  return <div>...</div>;
};

// 手动控制渲染耗时追踪
import { useManualComponentPerf } from 'fps-auto-report';

const MyComponent = () => {
  const { start, end } = useManualComponentPerf('MyComponent');
  
  const handleClick = () => {
    start();
    // ... 执行操作
    end('click:duration');
  };
  
  return <button onClick={handleClick}>Click</button>;
};

📖 详细文档

Vue Router 集成

v1.5.0 新增的 Vue Router 集成,自动追踪路由切换耗时。

// Vue 3
import { createRouter } from 'vue-router';
import { setupVueRouterPerf } from 'fps-auto-report';

const router = createRouter({ /* ... */ });

setupVueRouterPerf(router, {
  routeDelay: 300,  // 等待DOM更新的延迟时间
  debug: true
});

// Vue 2
import VueRouter from 'vue-router';
import { setupVue2RouterPerf } from 'fps-auto-report';

const router = new VueRouter({ /* ... */ });

setupVue2RouterPerf(router);

📖 详细文档

Babel 插件(自动插桩)

使用 Babel 插件自动为异步函数插入性能追踪代码,无需手动埋点。

📖 详细文档

# 安装插件
npm install --save-dev babel-plugin-fps-auto-report
// babel.config.js
module.exports = {
  plugins: [
    [
      'babel-plugin-fps-auto-report',
      {
        trackerName: 'PerfTracker',
        include: 'fetch|load|submit|get|post'
      }
    ]
  ]
};

插桩前:

async function fetchUserData(userId) {
  const response = await fetch(`/api/user/${userId}`);
  return response.json();
}

插桩后(自动):

async function fetchUserData(userId) {
  try {
    PerfTracker.mark('fetchUserData:exec:start');
  } catch (_e) {}
  const response = await fetch(`/api/user/${userId}`);
  try {
    PerfTracker.mark('fetchUserData:exec:end');
    PerfTracker.measure('fetchUserData:exec:duration', 'fetchUserData:exec:start', 'fetchUserData:exec:end');
  } catch (_e) {}
  return response.json();
}

📖 Babel 插件详细文档 | 测试报告

配置选项:

{
  trackerName: 'PerfTracker',        // 追踪器名称
  include: 'fetch|load|submit',      // 函数名匹配模式(正则)
  exclude: '^_|internal',            // 排除的函数名模式
  markPrefix: 'api:',                // 标记前缀
  measurePrefix: 'api:',             // 指标前缀
  autoMeasure: true,                 // 是否自动测量
  wrapInTryCatch: true               // 是否用 try-catch 包裹(默认 true)
}

配置选项

FPSReporterConfig

| 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | reportUrl | string | 否* | - | 上报接口地址(如果使用 customReporter 则可不填) | | reportMethod | 'POST' \| 'GET' \| 'PUT' \| 'PATCH' | 否 | 'POST' | 上报方法 | | customReporter | (data: ReportData) => void \| Promise<void> | 否 | - | 自定义上报函数 | | fpsInterval | number | 否 | 1000 | FPS 统计间隔(毫秒) | | enableWebVitals | boolean | 否 | true | 是否启用 web-vitals 统计 | | autoReport | boolean | 否 | true | 是否自动上报 | | reportInterval | number | 否 | 5000 | 上报间隔(毫秒) | | reportOnUnload | boolean | 否 | true | 是否在页面卸载时上报 | | collectPageInfo | () => PageInfo \| Promise<PageInfo> | 否 | 默认收集函数 | 自定义页面信息收集函数 | | headers | Record<string, string> | 否 | {} | 请求头配置 | | debug | boolean | 否 | false | 是否启用调试模式 | | logOnly | boolean | 否 | false | 日志模式:在此模式下所有上报都只打印日志,不进行真实上报 | | fpsReportStrategy | FPSReportStrategy | 否 | 见下方 | FPS 上报策略配置 | | webVitalsReportStrategy | WebVitalsReportStrategy | 否 | 见下方 | Web Vitals 上报策略配置 | | useBatchReport | boolean | 否 | false | 是否启用批量上报模式(v1.5.0) | | metricReporterConfig | MetricReporterConfig | 否 | - | MetricReporter 配置(v1.5.0) |

FPSReportStrategy

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | enabled | boolean | true | 是否启用 FPS 上报 | | levelBased | boolean | true | 是否启用基于等级的智能上报 | | interval | number | 5000 | 固定上报间隔(毫秒,当 levelBased 为 false 时使用) | | levelThresholds | FPSLevelThresholds | 见下方 | FPS 等级阈值配置 | | levelStrategy | FPSLevelReportStrategy | 见下方 | FPS 等级上报策略配置 |

WebVitalsReportStrategy

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | enabled | boolean | true | 是否启用 Web Vitals 上报 | | reportOnChange | boolean | true | 指标变化时立即上报(推荐) | | reportOnFirst | boolean | true | 指标首次出现时上报 | | reportInterval | number | 5000 | 固定上报间隔(毫秒,当 reportOnChange 为 false 时使用) |

数据类型

ReportData

上报的数据结构:

interface ReportData {
  fps?: FPSData;                    // FPS 统计数据
  webVitals?: Metric[];             // web-vitals 指标数组
  exposure?: ExposureEvent | ExposureEvent[];  // 曝光数据(单个或多个)
  pageInfo: PageInfo;               // 页面信息
  timestamp: number;                // 时间戳
}

FPSData

FPS 统计数据:

interface FPSData {
  fps: number;             // 当前 FPS
  averageFPS: number;       // 平均 FPS
  minFPS: number;          // 最小 FPS
  maxFPS: number;          // 最大 FPS
  frameCount: number;       // 帧数
  timestamp: number;        // 时间戳
}

PageInfo

页面信息(可扩展):

interface PageInfo {
  url: string;             // 页面 URL
  title?: string;          // 页面标题
  referrer?: string;       // 来源页面
  userAgent?: string;      // 用户代理
  viewport?: {             // 视口大小
    width: number;
    height: number;
  };
  timestamp?: number;       // 时间戳
  [key: string]: any;      // 自定义字段
}

ExposureEvent

曝光事件数据:

interface ExposureEvent {
  elementId: string;              // 元素标识
  exposureCount: number;           // 曝光次数
  firstExposureTime: number;       // 首次曝光时间
  lastExposureTime: number;        // 最后曝光时间
  exposureRecords: Array<{        // 曝光记录列表
    timestamp: number;             // 曝光时间戳
    duration?: number;             // 曝光持续时间(毫秒)
  }>;
  elementInfo?: {                  // 元素信息
    tagName?: string;
    className?: string;
    id?: string;
    textContent?: string;
  };
}

上报策略说明

混合策略设计

本库采用混合上报策略,FPS、Web Vitals 和 Exposure 独立上报,互不耦合:

  • FPS 上报

    • 基于卡顿等级的智能上报(推荐):根据 FPS 值自动划分等级,不同等级采用不同上报频率
    • 固定间隔上报:按固定时间间隔上报
  • Web Vitals 上报

    • 事件驱动上报(推荐):指标变化或首次出现时立即上报,符合 Web Vitals 的特性
    • 固定间隔上报:按固定时间间隔上报
  • Exposure 上报

    • 立即上报(事件驱动):曝光确认后立即上报
    • 手动上报:开发者主动调用
    • 批量上报:与其他性能数据一起上报
    • 定时上报:按固定时间间隔上报

为什么需要混合策略?

  • FPS 是持续变化的实时指标,适合按等级动态调整上报频率
  • Web Vitals 指标通常在特定时机出现(如页面加载、用户交互),适合事件驱动上报
  • Exposure 是用户行为触发的指标,适合事件驱动或定时上报
  • 三者独立上报,避免相互影响,更符合各自的数据特性

注意事项

  1. 依赖要求:需要安装 web-vitals 作为 peer dependency
    • React Hook 需要安装 react(peer dependency)
    • Vue Router 集成需要安装 vue-router(peer dependency)
  2. 浏览器兼容性
    • 需要支持 requestAnimationFrameperformance.now() 的现代浏览器
    • 曝光追踪功能需要支持 IntersectionObserver API(IE 不支持)
    • 批量上报功能需要支持 localStorage API
  3. 上报接口:确保你的上报接口能够处理 JSON 格式的数据
  4. 页面卸载上报:使用 sendBeacon API 确保页面卸载时数据能够可靠上报
  5. 向后兼容:旧版配置(enableLevelBasedReportfpsLevelThresholds 等)仍然支持,但推荐使用新的策略配置
  6. 曝光追踪性能:已优化支持追踪大量元素(1000+),使用 Observer 复用和 WeakMap 自动 GC
  7. v1.5.0 新功能
    • 日志模式:logOnly 配置项,测试阶段只打印日志,不进行真实上报
    • 批量上报模式:启用后会自动使用 MetricReporter 进行批量上报
    • 采样控制:通过 sampleRateMap 配置不同页面的采样率
    • 离线缓存:自动缓存失败的上报数据,网络恢复后自动重试
    • 性能标记:使用 mark()measure() 进行手动埋点
    • Babel 插件:构建时自动插桩,无需手动埋点

开发

# 安装依赖
npm install

# 构建
npm run build

# 开发模式(监听文件变化)
npm run dev

License

MIT