UNPKG

vite-plugin-fps-meter

Version:

vite-plugin-fps-meter is a tiny Vite plugin that overlays a live FPS / ms badge (with p95/p99 and Long Task %) on your app. It can auto-inject in dev or build, toggles via URL/localStorage, adapts to Vite's error overlay, and exposes a simple runtime API.

141 lines (93 loc) 6.62 kB
<div align="center"> <br> <h1>vite-plugin-fps-meter</h1> <p><sup><strong>vite-plugin-fps-meter</strong> is a tiny Vite plugin that overlays a live <strong>FPS / ms</strong> badge (with <strong>p95/p99</strong> and <strong>Long Task %</strong>) on your app. It can auto-inject in dev or build, toggles via URL/localStorage, adapts to Vite's error overlay, and exposes a simple runtime API.</sup></p> [![npm](https://img.shields.io/npm/v/vite-plugin-fps-meter.svg?colorB=brightgreen)](https://www.npmjs.com/package/vite-plugin-fps-meter) [![GitHub package version](https://img.shields.io/github/package-json/v/ux-ui-pro/vite-plugin-fps-meter.svg)](https://github.com/ux-ui-pro/vite-plugin-fps-meter) [![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-fps-meter.svg?style=flat)](https://www.npmjs.org/package/vite-plugin-fps-meter) </div> <br>**Install** ```bash # yarn yarn add -D vite-plugin-fps-meter # pnpm pnpm add -D vite-plugin-fps-meter # npm npm i -D vite-plugin-fps-meter ``` <br>**Quick Start** ```ts // vite.config.ts import { defineConfig } from 'vite'; import fpsMeter from 'vite-plugin-fps-meter'; export default defineConfig({ plugins: [ fpsMeter({ // Show badge only in dev by default ("dev" | "build" | boolean) enabled: 'dev', // Optional fine-tuning (defaults shown below in Options) position: 'tl', maxDisplayFps: 240, }), ], }); ``` <br>**How it looks / Works** - Click the badge to cycle: **FPS → ms → p95 → p99**. - Long Task % shows how much time (in the last update window) was spent in [Long Tasks](https://developer.chrome.com/docs/devtools/evaluate-performance/reference#long-tasks) (if supported by the browser). - The badge will automatically move to the bottom if Vite's error overlay appears while your preferred position is top. - A tiny in-memory window is used to compute percentiles. <br>**Options** | Field | Type | Default | Description | |:----------------------:|:------------------------------------------------:|:------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------| | `enabled` | `boolean` &#124; `'dev'` &#124; `'build'` | `'dev'` | Controls when the runtime is injected and started. `'dev'` = Vite serve, `'build'` = during build preview/runtime, `true`/`false` to force on/off. | | `updateIntervalMs` | `number` | `250` | UI update interval (ms). | | `smoothingTauMs` | `number` | `300` | EMA smoothing time constant (ms). | | `skipFrameThresholdMs` | `number` | `400` | Skip frames with `dt` above this threshold (e.g., tab switches) to avoid skewing EMA. | | `pauseOnHidden` | `boolean` | `true` | Pause meter when `document.hidden` is true. | | `maxDisplayFps` | `number` | `240` | Cap displayed FPS. | | `position` | `'tl'` &#124; `'tr'` &#124; `'bl'` &#124; `'br'` | `'tl'` | Badge position: top/bottom & left/right. | | `zIndex` | `number` | `2147483647` | CSS z-index of the badge. | | `storageKey` | `string` | `'vite:fps-meter'` | LocalStorage key for persisted toggle. | | `showInIframe` | `boolean` | `true` | If `false`, the meter won't render inside iframes. | | `percentileWindowSize` | `number` | `300` | Number of recent frame durations used to compute `p95`/`p99`. | <br>**Runtime controls** - URL param: `?fps=1` to force-enable, `?fps=0` to force-disable on first load. - Persistence: state is saved in `localStorage['vite:fps-meter']` (customizable via `storageKey`). - Global API (injected): ```ts // Toggle at runtime window.__fpsMeter?.setEnabled(false); window.__fpsMeter?.setEnabled(true); // Read current state const on = window.__fpsMeter?.isEnabled(); ``` <br>**Programmatic init (advanced)** By default, the plugin auto-injects and auto-starts. If you need a custom instance, you can import the virtual client and mount manually: ```ts // Somewhere in your app (advanced usage) import initFpsMeter from 'virtual:fps-meter-client'; const dispose = initFpsMeter({ position: 'br' }); // ...later dispose(); ``` Note: manual init will create another badge in addition to the auto-injected one. Prefer the global API above unless you have a specific reason to manage instances yourself. <br>**Notes on metrics** - FPS and ms are derived from a smoothed EMA of frame durations. - `p95`/`p99` are computed over a small sliding window of recent frames to avoid heavy allocations. - Long Task % uses `PerformanceObserver` with `{ type: 'longtask', buffered: true }`. If unsupported, it's silently disabled. <br>**Compatibility** - Vite: peer dependency `^5` &#124; `^6` &#124; `^7`. - Node: `>=18`. - Works in iframes unless `showInIframe: false` is set. <br>**License** MIT