Performance and best practices#

This page summarizes patterns that keep visualizations responsive and scalable.

Renderer lifecycle#

Each renderer tracks when its GPU state was last updated using an internal timestamp. On a new render pass, only renderers whose data changed need to rebuild pipelines or buffers.

To work with this mechanism:

  • Reuse renderer instances and update their data instead of recreating them on every change.

  • Call renderer.set_needs_update() after modifying large arrays or other state that should be copied to GPU buffers.

Data layout#

Careful data layout avoids unnecessary copies and conversions:

  • Use contiguous numpy arrays with explicit dtype (typically float32 or uint32) before creating GPU buffers.

  • Pack related attributes together where it matches the shader layout to minimise the number of separate buffers.

Drawing many objects#

For large numbers of similar objects, prefer instanced rendering over many independent renderers:

  • Use webgpu.shapes.ShapeRenderer (or similar instanced renderers) with per-instance attribute arrays.

  • Batch updates to instance data where possible instead of modifying thousands of small Python objects.

Interaction and responsiveness#

  • Avoid performing heavy CPU work inside selection callbacks or GUI event handlers; move such work into separate functions or background jobs where practical.

  • Keep shader code simple and data-parallel; avoid unnecessary branching in inner loops.

These guidelines, together with the architectural overview and examples in the other user-guide pages, should give you a solid baseline for building efficient visualizations with webgpu.