Why you might want to build your WebApp in Canvas instead of HTML

I’m always curious how Google, Microsoft and Co. build their web apps - given that they need to work well on any computer, from a top-shelf speed machine to a potato with wires.

Of course, there are many answers to this question - but one that I find particularly interesting is their use of the Canvas element for functionality that’s usually implemented in HTML.

The document in Google Docs is a Canvas. So is the sheet in Google Sheets or in the web version of Excel. Unsurprisingly, Canva is a Canvas - but so is the board in Miro. Our own scheduling interface in Hivekit is also a Canvas.

Hivekit's scheduler can be zoomed (changes displayed timespan), panned in x and y direction and has lots of interactive aspects that needed managing.

I helped build it, and in this post, I want to explain why we chose Canvas over DOM elements, what we learned along the way, when I think that Canvas is or isn’t a good choice for web apps, and why I think Canvas is used by all these big companies for performance-critical apps.

What was Canvas again?

Canvas has been around for more than 20 years now. It provides a blank space within an HTML document that can be drawn on. To do that, you use a JavaScript API with higher-level methods like fillRect() to fill a rectangle and lower-level methods like getImageData() to access the raw RGBA values of your pixels.

Whatever approach you take, you end up with what’s basically a static image. For Web Developers, that feels a bit odd. After all, they’re used to a complex Document Object Model, HTML parsed into element trees, click handlers and event bubbling, dynamic rendering and reflows - all managed for you and perfectly tuned for the user’s device.

With Canvas, all of this is gone now.

So - why on earth would you use Canvas?

There are some things only Canvas can do. Pixel image manipulation is the obvious one. But why would you choose Canvas to build a web app that could also be built in HTML?

A few reasons:

And why wouldn’t you use Canvas?

There are far more reasons not to use Canvas than to use it. And for most web apps, you’re much better off with good old DOM elements. Take the humble <input type="text"> element, for example. With it, you get crispy rendering at any resolution, support for tab, focus, selection, mouse interactions and arrow key navigation, internationalization for right-to-left text and Asian compound characters, accessibility for screen readers… the list goes on.

Browsers give you a lot of functionality out of the box and there are plenty of great frameworks that make it easy to use, scale and work on in an organized and standardized way across teams.

When is Canvas the better choice?

There’s a certain set of use cases where Canvas can be the better choice.

But if you do decide on a Canvas implementation, here are some of the key things you want to look out for:

class Renderer{
    constructor(canvas){
        this.renderScheduled = false;
        this.canvas = canvas;
        this.context = canvas.getContext('2d');
        this.backgroundRenderer = new BackgroundRenderer(this);
        this.rowRenderer = new RowRenderer(this);
    }

    scheduleRender(){
        if(this.renderScheduled) return;
        this.renderScheduled = true;
        requestAnimationFrame(this.render.bind(this));
    }

    render() {
        this.renderScheduled = false;
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);

        // Render the individual layers in order
        this.backgroundRenderer.render(this.context);
        this.rowRenderer.render(this.context);
    }
}
gapDiagonalLineSpacing: 10,
textColor: '#ecf0f5', 
textColorSecondary: '#4d6585',
fontStyle: "13px 'Lato', sans-serif",
fontStyleBold: "bold 13px 'Lato', sans-serif"
...
getPixelScale() {
    return Math.max(window.devicePixelRatio, 1);
}
scaleCanvas(canvas, ctx) {
    const pixelScale = this.getPixelScale();
    canvas.width = canvas.offsetWidth * pixelScale;
    canvas.height = canvas.offsetHeight * pixelScale;
    ctx.scale(pixelScale, pixelScale);
}

So, should you use Canvas?

Canvas isn’t a faster replacement for HTML. It’s a lower-level rendering tool that gives you more control—and makes you responsible for much more of the browser’s work.

For most web apps, the DOM remains the better choice. It gives you accessibility, responsive layouts, text selection, input handling, and countless other features for free. But if the heart of your application is a large, spatial workspace with complex positioning, zooming, panning, or thousands of visual elements, Canvas may be a better fit.

That was the case for us. Owning the rendering pipeline made the planning interface easier to reason about and gave us predictable performance across a wide range of devices. It also meant building our own systems for interaction, hit testing, scaling, and rendering—work that shouldn’t be underestimated.

So don’t choose Canvas simply because it sounds fast. Choose it when your interface no longer behaves like a document and starts behaving more like a scene.