# Performance

The render cache, the undo budget, the render worker switch and the per-page pixel budget.

- Interface: `PerformanceConfig`
- Config path: `config.performance`

## Example

```ts
new PDFViewer(container, doc, {
  performance: {
    renderCacheSize: 8,
    workerEnabled: false, // keep rendering on the main thread: the engine loads once, not twice
  },
});
```

## Options (5)

### `renderCacheSize`

- Type: `number`
- Default: `5`
- Page: https://kernstra.com/docs/web-sdk/config/performance/rendercachesize

Rendered pages kept in memory, those on screen included (never fewer than the visible pages + 2), when pages render on demand: over 50 pages, a smaller document too large or slow to render whole, any document on a phone or tablet, or once the render worker is running.

### `undoHistoryLimit`

- Type: `number`
- Default: `20`
- Page: https://kernstra.com/docs/web-sdk/config/performance/undohistorylimit

Max undo snapshots.

### `undoByteBudget`

- Type: `number`
- Default: `256 MiB`
- Page: https://kernstra.com/docs/web-sdk/config/performance/undobytebudget

Byte cap across undo snapshots. Oldest snapshots are dropped beyond it (at least two are always kept).

### `workerEnabled`

- Type: `boolean`
- Default: `true`
- Page: https://kernstra.com/docs/web-sdk/config/performance/workerenabled

Use a Web Worker for rendering. Only takes effect when a `workerUrl` is provided in [`Kernstra.init()`](https://kernstra.com/docs/web-sdk/config/init/workerurl) (see [Web worker rendering](https://kernstra.com/docs/web-sdk/guides/worker) for what the worker is given under each license). Otherwise rendering always runs on the main thread regardless of this flag. Set `false` to keep rendering on the main thread even when a worker URL is available: the engine then loads once instead of twice (for low-memory devices), and it suits environments where Web Workers are restricted. See [Web worker rendering](https://kernstra.com/docs/web-sdk/guides/worker).

```ts
performance: { workerEnabled: false }
```

### `maxRenderPixels`

- Type: `number`
- Default: `2^24`
- Page: https://kernstra.com/docs/web-sdk/config/performance/maxrenderpixels

Pixel budget per bitmap: a page's, and the full-resolution layer over a page zoomed past it. It bounds every bitmap the viewer draws a page into (width × height in device pixels). A page whose whole bitmap would exceed it is drawn at a lower resolution and stretched to its on-screen size instead of allocating a runaway bitmap — an A4 page at 800% zoom on a 2× display is ~128M pixels (512MB) otherwise, and iOS Safari refuses a canvas over 2^24 pixels. The part of such a page in view is then drawn again at the screen's full resolution, into a second bitmap laid over it and held to the same budget, so text and vector art stay sharp at every zoom up to [`navigation.maxZoom`](https://kernstra.com/docs/web-sdk/config/navigation/maxzoom) on a 2× display. That layer is drawn once scrolling settles and after the page itself, follows the page through a zoom, is held only for pages in view, and is not counted in `renderCacheSize`. The default is 2^24 (about 16.7M pixels). The budget also bounds the bitmap each printed page is rendered to: a page whose 300 dpi raster would exceed it prints at a lower resolution (printing draws no full-resolution layer).

## Notes

**On a coarse pointer** — a phone, a tablet (`data-ks-pointer="coarse"`, or `layout.pointer: 'coarse'`) — the screen's bitmaps are held to a quarter of `maxRenderPixels`: 2^22 by default, so a page bitmap is at most 16 MB rather than 64 MB. A phone's canvases live under a hard memory cap of a few hundred megabytes and its process under one of about two gigabytes; at a 3× pixel density an A3 sheet reaches the full budget at a zoom of 136%, and five such pages kept are 320 MB of canvas before the layer over them. The part in view is drawn sharp by that layer in any case, so the page bitmap beneath it loses nothing a finger can see. Printing keeps the full budget. Set `maxRenderPixels` to the budget you want on a desktop; the phone's share follows.

**Heavy-document behavior.** Scrolling through large, image-heavy documents stays responsive: page renders queued for pages that scroll back out of view are dropped before they spend render time, thumbnails render one at a time under the same rule, rendered pixels are painted to the canvas in a single pass, and the full-resolution layer over a page zoomed past `maxRenderPixels` waits until the page renders are done and the scroll has settled, one at a time, dropped when its page leaves the view or changes meanwhile. Together these keep the pages currently on screen first in line no matter how fast the user scrolls.

The Manage Pages dialog follows the same rules: it opens instantly and renders only the page tiles near its grid viewport, filling in the rest as the grid is scrolled.


Web page: https://kernstra.com/docs/web-sdk/config/performance
