How to Show FPS Using Matter.Render in Matter.js

This article explains how to display real-time performance metrics, specifically frames per second (FPS), using the built-in rendering capabilities of Matter.js. You will learn how to enable the native FPS overlay directly through Matter.Render configuration options, as well as how to draw customized performance indicators using render lifecycle events.

Method 1: Using Built-in Render Options

The quickest way to show FPS in Matter.js is by toggling the built-in debug options available in Matter.Render. When initializing your renderer with Render.create, you can enable showFPS inside the options object.

const { Engine, Render, Runner, Composite, Bodies } = Matter;

const engine = Engine.create();

const render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 800,
    height: 600,
    wireframes: false,
    showFPS: true // Enables the built-in real-time FPS counter
  }
});

Render.run(render);

const runner = Runner.create();
Runner.run(runner, engine);

When showFPS is set to true, Matter.js automatically computes the frame rate and draws the FPS metric directly onto the canvas in the top corner.


Method 2: Custom Metrics via the afterRender Event

If you need more control over styling, positioning, or want to track additional statistics like body counts and delta times, hook into the afterRender event. This hook provides direct access to the canvas context after the physics bodies are drawn.

const { Engine, Render, Runner, Events } = Matter;

const engine = Engine.create();
const render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 800,
    height: 600,
    wireframes: false
  }
});

let lastTime = performance.now();
let frameCount = 0;
let fps = 0;

Events.on(render, 'afterRender', () => {
  const currentTime = performance.now();
  frameCount++;

  // Update FPS calculation every second
  if (currentTime - lastTime >= 1000) {
    fps = frameCount;
    frameCount = 0;
    lastTime = currentTime;
  }

  // Draw custom metrics on top of the physics canvas
  const context = render.context;
  context.save();
  context.font = '14px monospace';
  context.fillStyle = '#00FF00';
  context.fillText(`FPS: ${fps}`, 10, 20);
  context.fillText(`Bodies: ${engine.world.bodies.length}`, 10, 40);
  context.restore();
});

Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);

Using render.options.showFPS is sufficient for quick debugging, while the afterRender event pattern offers full flexibility for custom user interfaces and extended performance diagnostics.