Skip to main content

HTML5 Canvas Shape Caching Performance Tip

If you have a complex shape with many drawing operations, or if you're applying filters, you can improve performance by caching the shape. When you cache a shape, Konva will draw it onto an internal canvas buffer. After that, instead of redrawing the shape every time, Konva will simply use the cached version.

This is particularly useful for:

  1. Complex shapes with many drawing operations
  2. Shapes with filters
  3. Shapes that don't change often but need to be redrawn frequently

To cache a shape, simply call the cache() method. You can clear the cache with clearCache().

Below is a demo showing the performance difference between cached and non-cached complex shapes:

import Konva from 'konva';

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
});

const layer = new Konva.Layer();
stage.add(layer);

// Create a complex shape (star with blur filter)
const createComplexShape = (x, isCached) => {
  const star = new Konva.Star({
    x: x,
    y: 100,
    numPoints: 20,
    innerRadius: 40,
    outerRadius: 70,
    fill: 'yellow',
    stroke: 'black',
    strokeWidth: 4,
  });

  // Add blur filter
  star.filters([Konva.Filters.Blur]);
  star.blurRadius(5);

  // Cache the shape if specified
  if (isCached) {
    star.cache();
  }

  return star;
};

// Create non-cached shape
const nonCachedStar = createComplexShape(100, false);

// Create cached shape
const cachedStar = createComplexShape(250, true);

// Add labels
const nonCachedLabel = new Konva.Text({
  x: 50,
  y: 200,
  text: 'Non-Cached Shape',
  fontSize: 16,
});

const cachedLabel = new Konva.Text({
  x: 200,
  y: 200,
  text: 'Cached Shape\n(Better Performance)',
  fontSize: 16,
});

// Add FPS counter
const fpsText = new Konva.Text({
  x: 10,
  y: 10,
  text: 'FPS: 0',
  fontSize: 16,
});

layer.add(nonCachedStar);
layer.add(cachedStar);
layer.add(nonCachedLabel);
layer.add(cachedLabel);
layer.add(fpsText);

// Create animation to demonstrate performance
const anim = new Konva.Animation((frame) => {
  nonCachedStar.rotation(frame.time * 0.1);
  cachedStar.rotation(frame.time * 0.1);
  
  // Update FPS counter
  fpsText.text('FPS: ' + frame.frameRate.toFixed(1));
}, layer);

anim.start();