# Performance

```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { loadMesh, recenterPolygons } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "solid", colorEncoding: "spans" });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const { polygons } = await loadMesh("/gallery/glb/Octopus.glb", { solidTextureSamples: false });
scene.add(recenterPolygons(polygons));
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Drag while changing density; watch the cell count and FPS. Doubling density roughly quadruples cells. Geometry, shading, color runs, and browser painting also contribute; a cube and a complex model do not have identical costs.

## Keep gestures responsive

```ts
scene.setOptions({ interactiveDownscale: 2 });
```

The bundled controls lower resolution during gestures and restore it on release. Custom controls call `scene.setInteracting(true)` / `false`.

## Spans, not just cells: `colorTolerance`



```ts
import { createGlyphPerspectiveCamera, createGlyphScene, createGlyphOrbitControls } from "glyphcss";
import { loadMesh, recenterPolygons } from "@glyphcss/core";

const host = document.getElementById("scene");
const camera = createGlyphPerspectiveCamera({ rotX: 65, rotY: 0, zoom: 0.3, distance: 0, perspective: 32000, stretch: 1 });
const scene = createGlyphScene(host, { camera, autoSize: true, mode: "solid", colorEncoding: "spans", colorTolerance: 0 });
scene.output.style.fontSize = "10px";
scene.output.style.lineHeight = "1";
scene.fit();
const { polygons } = await loadMesh("/gallery/glb/Watermelon.glb", { solidTextureSamples: false });
scene.add(recenterPolygons(polygons));
createGlyphOrbitControls(scene, { drag: true, wheel: true });
```



Tolerance merges nearby color runs, trading fidelity for fewer spans. Default `0`: off; range `0–765`; try `24–128`. Semantic output ignores it. [Atlas encoding](/guides/color-encoding/) removes spans for compatible output.

- Use detail layers and hotspots sparingly: each adds per-render work.
- Rerender when state changes; leave idle scenes idle.
- Animate hotspot DOM with CSS when the mesh does not change.
