or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-stats-js

JavaScript Performance Monitor for real-time FPS and frame timing statistics

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/stats.js@1.0.x

To install, run

npx @tessl/cli install tessl/npm-stats-js@1.0.0

index.mddocs/

stats.js

stats.js is a lightweight JavaScript performance monitoring library that provides a visual widget for displaying real-time FPS (frames per second) and frame render time statistics. It creates a compact DOM-based overlay that can be embedded in web applications for performance debugging and optimization.

Package Information

  • Package Name: stats.js
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install stats.js

Core Imports

// CommonJS
const Stats = require('stats.js');

// ES Modules (if using a bundler)
import Stats from 'stats.js';

Browser direct include:

<script src="path/to/stats.min.js"></script>
<!-- Stats constructor is available globally -->

Basic Usage

// Create a new performance monitor
const stats = new Stats();

// Position the widget (usually top-left corner)
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);

// Option 1: Manual measurement
function gameLoop() {
    stats.begin();
    
    // Your performance-critical code here
    // (game rendering, calculations, etc.)
    
    stats.end();
    requestAnimationFrame(gameLoop);
}

// Option 2: Convenience method
function gameLoop() {
    stats.update(); // Equivalent to calling end() then begin()
    
    // Your performance-critical code here
    
    requestAnimationFrame(gameLoop);
}

// Start the loop
requestAnimationFrame(gameLoop);

Architecture

stats.js is built around several key design patterns:

  • DOM Widget System: Creates a self-contained visual widget using dynamically generated DOM elements with inline styling
  • Dual Display Modes: Interactive toggle between FPS (frames per second) and MS (milliseconds per frame) measurement modes
  • Performance Timing: Uses high-precision timing APIs (performance.now() with Date.now() fallback) for accurate measurements
  • Real-time Visualization: Live-updating graph bars that show performance history over time
  • Event-driven Interaction: Mouse click handling for mode switching with visual feedback
  • Modular Measurement: Flexible begin/end pattern allows measurement of arbitrary code blocks

Capabilities

Stats Constructor

Creates a new performance monitoring widget instance with interactive display modes.

/**
 * Creates a new Stats performance monitor widget
 * @constructor
 * @returns {Object} Stats instance with methods and properties
 */
function Stats();

The widget automatically creates a visual display with:

  • FPS Mode (Mode 0): Shows frames per second with min/max tracking (blue/cyan theme)
  • MS Mode (Mode 1): Shows milliseconds per frame with min/max tracking (green theme)
  • Interactive Toggle: Click the widget to switch between modes

Instance Properties

interface StatsInstance {
  /** Library revision number (currently 13) */
  REVISION: number;
  
  /** The widget's container DOM element that can be appended to the document */
  domElement: HTMLDivElement;
}

Performance Measurement

Core methods for measuring code performance within a frame or time period.

/**
 * Marks the beginning of a performance measurement frame
 * Call before the code you want to measure
 */
begin(): void;

/**
 * Marks the end of a performance measurement frame and updates display
 * Call after the code you want to measure
 * @returns {number} Current timestamp (from performance.now() or Date.now())
 */
end(): number;

/**
 * Convenience method that calls end() then immediately begins a new measurement
 * Useful for continuous monitoring in animation loops
 */
update(): void;

Usage Examples:

const stats = new Stats();
document.body.appendChild(stats.domElement);

// Measuring a specific operation
stats.begin();
performExpensiveCalculation();
stats.end();

// Measuring in an animation loop
function animate() {
    stats.begin();
    
    // Render scene, update game logic, etc.
    renderScene();
    updatePhysics();
    
    stats.end();
    requestAnimationFrame(animate);
}

// Alternative using update() method
function animate() {
    stats.update();
    
    // Your code here runs after measurement ends and new one begins
    renderScene();
    updatePhysics();
    
    requestAnimationFrame(animate);
}

Display Mode Control

Control which performance metric is displayed in the widget.

/**
 * Sets the display mode of the performance monitor
 * @param {number} value - Display mode (0 = FPS mode, 1 = MS mode)
 */
setMode(value: number): void;

Usage Examples:

const stats = new Stats();

// Start in FPS mode (default)
stats.setMode(0);

// Switch to milliseconds mode
stats.setMode(1);

// Toggle between modes programmatically
let currentMode = 0;
function toggleMode() {
    currentMode = (currentMode + 1) % 2;
    stats.setMode(currentMode);
}

Display Modes

FPS Mode (Mode 0)

  • Purpose: Displays frames rendered per second with minimum and maximum tracking
  • Color Scheme: Blue/cyan background (#002, #0ff)
  • Interpretation: Higher numbers indicate better performance
  • Graph: Real-time histogram showing FPS variations over time

MS Mode (Mode 1)

  • Purpose: Displays milliseconds needed to render each frame with min/max tracking
  • Color Scheme: Green background (#020, #0f0)
  • Interpretation: Lower numbers indicate better performance
  • Graph: Real-time histogram showing frame time variations

Styling and Theming

The widget can be customized using CSS by targeting specific element IDs:

/* Main container */
#stats {
    width: 80px;
    opacity: 0.9;
    cursor: pointer;
}

/* FPS mode styling */
#fps { /* Container for FPS display */ }
#fpsText { /* FPS text label */ }
#fpsGraph { /* FPS graph container */ }

/* MS mode styling */
#ms { /* Container for MS display */ }
#msText { /* MS text label */ }
#msGraph { /* MS graph container */ }

Browser Compatibility

  • Timing API: Uses performance.now() when available, falls back to Date.now()
  • DOM Requirements: Requires document.createElement and basic DOM manipulation
  • Module Support: Works with CommonJS (module.exports) and global variable patterns
  • Zero Dependencies: No external libraries required

Integration Patterns

Game Development

const stats = new Stats();
stats.domElement.style.position = 'fixed';
stats.domElement.style.top = '0';
stats.domElement.style.right = '0';
stats.domElement.style.zIndex = '10000';
document.body.appendChild(stats.domElement);

function gameLoop(timestamp) {
    stats.begin();
    
    updateGame(timestamp);
    renderGame();
    
    stats.end();
    requestAnimationFrame(gameLoop);
}

Web Application Monitoring

// Monitor specific operations
function monitoredFunction() {
    stats.begin();
    try {
        // Heavy computation or rendering
        processLargeDataSet();
        updateUI();
    } finally {
        stats.end(); // Ensure measurement ends even if errors occur
    }
}

// Monitor animation performance
function smoothAnimation() {
    stats.update();
    // Animation code here
    animateElements();
    requestAnimationFrame(smoothAnimation);
}

Development Debug Tool

// Only show stats in development
if (process.env.NODE_ENV === 'development') {
    const stats = new Stats();
    stats.setMode(1); // Start with MS mode for development
    document.body.appendChild(stats.domElement);
    
    // Make it draggable or add toggle button
    stats.domElement.style.position = 'fixed';
    stats.domElement.style.top = '10px';
    stats.domElement.style.left = '10px';
    stats.domElement.style.zIndex = '9999';
}