THN Interview Prep

Canvas, workers & graphics

Canvas and graphics-heavy UIs require a different model from DOM apps. The browser does not retain semantic elements for each shape you draw. You own the scene model, redraw strategy, input mapping, accessibility fallback, and performance budget.

Core details

ConceptMeaningRisk
Immediate modeCanvas draws pixels now; it does not remember objectsmust redraw after every change
Retained scene modelyour app stores shapes/entities separatelybugs when pixels and model drift
Render loopusually driven by requestAnimationFramework can exceed frame budget
Coordinate spaceCSS pixels, device pixels, transforms, camerablurry or incorrect hit testing
Hit testingmap pointer to scene objectexpensive search or wrong transforms
OffscreenCanvasrender in a Worker when supportedtransfer and messaging overhead
Accessibilitycanvas has no built-in semantic treeneed DOM controls, labels, summaries, keyboard path

Canvas contexts: 2d for immediate drawing, WebGL/WebGPU for GPU pipelines, and bitmap/offscreen APIs for specialized workloads. Choose based on workload, team expertise, browser support, and debugging cost.

requestAnimationFrame: schedule visual updates before paint. It is one-shot, so continuous animation must request the next frame. Avoid setInterval for animation timing.

Workers: use Workers for CPU-heavy parsing, simulation, image processing, geometry, compression, or OffscreenCanvas rendering. Workers cannot mutate DOM directly.

Understanding

Canvas is fast when you control the amount of drawing and memory. It becomes slow when every frame redraws too much, allocates objects, decodes images, performs expensive hit testing, or copies large payloads between threads.

The first architecture decision is whether the UI is truly graphics-first. If users need selectable text, forms, links, accessible controls, and layout, the DOM may be the primary surface with small canvas regions. If the product is a map, editor, waveform, game, charting engine, or whiteboard, a retained scene model plus canvas renderer can make sense.

High-DPI rendering matters. A canvas styled at 500 by 300 CSS pixels may need a 1000 by 600 backing store on a 2x screen. Without scaling, graphics look blurry; with careless scaling, memory doubles in each dimension.

Practical examples

High-DPI setup:

function resizeCanvas(canvas: HTMLCanvasElement) {
  const dpr = window.devicePixelRatio || 1;
  const rect = canvas.getBoundingClientRect();
  canvas.width = Math.round(rect.width * dpr);
  canvas.height = Math.round(rect.height * dpr);
  const ctx = canvas.getContext("2d")!;
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  return ctx;
}

Render loop shape:

let rafId = 0;

function frame(time: number) {
  updateSimulation(time);
  drawScene();
  rafId = requestAnimationFrame(frame);
}

rafId = requestAnimationFrame(frame);

Architecture choices:

NeedGood approach
Static chartSVG or DOM may be simpler and accessible
Thousands of moving pointsCanvas/WebGL with spatial index
Text editingDOM overlay or specialized editor model
Heavy image processingWorker + OffscreenCanvas where supported
Whiteboardretained scene model + dirty-region redraw

Senior understanding

ProbeStrong answer
“Canvas vs SVG?”Canvas for many pixels/objects; SVG/DOM for semantics and inspectable shapes
“Why Worker?”Move CPU/rendering off main thread, but account for transfer cost
“Hit testing?”Use scene graph, transforms, spatial index, and pointer capture
“Accessibility?”Provide keyboard/DOM equivalents, labels, summaries, and non-visual workflows

Failure modes

  • Redrawing the full scene every frame when only a small region changed.
  • Allocating new objects in hot draw loops and creating GC jank.
  • Ignoring device pixel ratio and producing blurry output.
  • Copying huge arrays between Worker and main thread every frame.
  • Building an inaccessible canvas-only control for form-like UI.

Diagram

Loading diagram…

See also

Spotted something unclear or wrong on this page?

On this page