Takumi

Performance & Optimization

Reuse rendering work and measure before tuning caches.

Reuse the renderer

import {  } from "takumi-js";

const  = await (< ="p-8 text-4xl">Hello Takumi</>, {
  : 1200,
  : 630,
});

render and ImageResponse reuse a managed renderer. No cache setup is needed. When using Renderer directly, create it outside the request handler so registered fonts and decoded resources survive between renders.

Know what is cached

WorkLifetimeConfiguration
Decoded images, SVG rasters, parsed stylesheetsRenderercacheMaxBytes, 16 MiB by default
Glyph outlines and rasterized masksLoaded backend modulesetGlyphCacheMaxBytes, 8 MiB by default
Parsed Tailwind classesLoaded backend moduleAutomatic, bounded internally
Resolved Tailwind declarationsRenderAutomatic, separated by viewport width, font size, and pixel ratio
Google Fonts CSSFetch implementationAutomatic, bounded internally
Downloaded image bytesCaller-provided cacheOptional images.fetchCache

Cache budgets account for retained entries, not total process memory. Fonts, active renders, output buffers, and allocator overhead use memory too. See image caching and Google Fonts for resource-specific behavior.

Measure cold and repeated renders

Measure the first render separately from repeated renders. Font downloads and decoding affect startup; layout, painting, and encoding still happen on a warm renderer.

Use representative text, images, output formats, and concurrent requests. Compare latency and memory before changing a budget. Increasing a cache helps only when it keeps work that later renders reuse.

Resource cache

import {  } from "takumi-js/node";

const  = new ({ : 64 * 1024 * 1024 });

Raise the budget when frequently reused images or stylesheets are being evicted. For images used only once, cache: "none" avoids displacing reusable entries. An unbounded images.fetchCache is separate from this budget.

Glyph cache

import {  } from "takumi-js";

(64 * 1024 * 1024);

Call this before the first render. Outlines and masks share the budget across renderers in the same backend module. Large glyph sets or text sizes can benefit from more space, but benchmark your content first.

Keep network requests out of repeated work

Bundle fonts for predictable startup without a font service. WOFF2 saves transfer and storage space but needs decompression; TTF avoids that step. A reused renderer decodes a registered file once. See local fonts and CI.

For repeated remote images, use a bounded fetch cache. The renderer's decode cache does not replace a download cache.

Reduce painting work

Each filtered node needs an offscreen layer. Put filters on one node when they should apply to the same composed content. Moving filters from children to a parent can change the output, so compare the result.

On servers, the native backend supports multithreaded rendering. The Wasm backend is single-threaded. takumi-js selects the backend for the environment; use explicit backend imports only when you need to control that choice.

Last updated on

On this page