# Performance API

> enableDirtyRegionRendering options and stats, the frame time monitor, batched canvas updates and the spatial index, from fabricjs-document-engine/performance.

Source: https://fabricjs-document-engine.jscrate.dev/docs/api/performance-api
Last updated: 2026-10-02

How enableDirtyRegionRendering decides what to draw, and the measured speed, is in the [Rendering many objects](https://fabricjs-document-engine.jscrate.dev/docs/guides/rendering-performance) guide.

```ts
import {
  batchCanvasUpdates,
  createPerformanceMonitor,
  createSpatialIndex,
  enableDirtyRegionRendering,
} from "fabricjs-document-engine/performance";
```

## enableDirtyRegionRendering

```ts
function enableDirtyRegionRendering(canvas: StaticCanvas, options?: DirtyRegionOptions): DirtyRegionRenderer
```

Redraws only what changed on a canvas. Exports always draw in full.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `fullRedrawRatio` | `number` | `0.4` | Draw the whole canvas when the changed area is larger than this share of it. |
| `maxRegions` | `number` | `4` | Most rectangles to clip to; more are merged. |
| `cellSize` | `number` | `256` | Cell size of the grid index, in canvas units. |

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `invalidate` (required) | `(): void` | — | Draws the next frame in full, for changes made inside a custom object's `_render`. |
| `stats` (required) | `(): DirtyRegionStats` | — | Counts and the regions of the last frame. |
| `disable` (required) | `(): void` | — | Puts Fabric's rendering back. |

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `frames` (required) | `number` | — | Frames drawn since enabled. |
| `fullFrames` (required) | `number` | — | Frames drawn in full. |
| `skippedFrames` (required) | `number` | — | Frames where nothing changed, so nothing was drawn. |
| `lastObjectsDrawn` (required) | `number` | — | Objects drawn in the last frame. |
| `lastAreaRatio` (required) | `number` | — | Share of the canvas drawn in the last frame, 0 to 1. |
| `lastRegions` (required) | `Rect$1[]` | — | The rectangles drawn in the last frame, in canvas pixels. |

## createPerformanceMonitor

```ts
function createPerformanceMonitor(canvas: StaticCanvas, options?: PerformanceMonitorOptions): PerformanceMonitor
```

Records frame times and objects drawn for a canvas.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `samples` | `number` | `120` | How many recent frames to keep. |

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `stats` (required) | `(): FrameStats` | — | Frame times and objects drawn. |
| `reset` (required) | `(): void` | — | Forgets the recorded frames. |
| `stop` (required) | `(): void` | — | Stops recording. |

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `frames` (required) | `number` | — | Frames recorded, up to `samples`. |
| `averageMs` (required) | `number` | — | Average frame time. |
| `p50Ms` (required) | `number` | — | Median frame time. |
| `p95Ms` (required) | `number` | — | 95th percentile frame time: the slow frames users notice. |
| `worstMs` (required) | `number` | — | Slowest frame. |
| `lastObjectsDrawn` (required) | `number` | — | Objects drawn in the last frame. |

## batchCanvasUpdates

```ts
function batchCanvasUpdates<Result>(canvas: StaticCanvas, work: () => Result): Result
```

Runs many adds and changes with one render at the end. Nests and works with async work.

## createSpatialIndex

```ts
function createSpatialIndex<Item>(options?: SpatialIndexOptions): SpatialIndex<Item>
```

A grid index for finding items near a rectangle.

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `cellSize` | `number` | `256` | Grid cell size in canvas units. |
| `maxCellsPerItem` | `number` | `64` | Items covering more cells than this go in a list every query returns. |

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `set` (required) | `(item: Item, bounds: Rect): void` | — | Adds an item, or moves it. |
| `delete` (required) | `(item: Item): boolean` | — | Removes an item. |
| `has` (required) | `(item: Item): boolean` | — | Whether the item is indexed. |
| `query` (required) | `(bounds: Rect): Set<Item>` | — | Items whose bounds may meet the rectangle. |
| `clear` (required) | `(): void` | — | Removes every item. |
| `size` (required) | `number` | — | How many items are indexed. |

The renderer from enableDirtyRegionRendering uses this same index with a cell size of 256. Call the renderer's `disable()` before you dispose of the canvas.
