demo · v142 · dom

Raw vs Coalesced Pointer Comparator

Draw freehand on the split canvas. The left half captures every pointerrawupdate event; the right uses pointermove with getCoalescedEvents(). Watch the point-density counters diverge — raw events arrive faster than the browser’s animation frame rate.

5
LEFT — pointerrawupdate
RIGHT — pointermove + getCoalescedEvents()
Raw points
0
Coalesced points
0
Ratio raw/coal
—
Smoothing factor
—

How it works

The browser coalesces pointer events to match the display refresh rate (typically 60 Hz). pointerrawupdate fires at the device polling rate (often 125–1000 Hz for a stylus or gaming mouse). Drawing on the left canvas registers every raw sample; the right uses pointermove plus getCoalescedEvents() to recover batched points. The ratio shows how aggressively the browser batched before your pointermove handler ran.

Code

// Secure context required for pointerrawupdate (Chrome 142+)
const isSecure = window.isSecureContext;
const supportsRaw = "onpointerrawupdate" in window || isSecure;

if (supportsRaw) {
  canvas.addEventListener("pointerrawupdate", (e) => {
    // fires at hardware polling rate — may be hundreds of Hz
    drawPoint(e.clientX, e.clientY);
  });
} else {
  // fallback: use coalesced events
  canvas.addEventListener("pointermove", (e) => {
    const coalesced = e.getCoalescedEvents();
    for (const ce of coalesced) {
      drawPoint(ce.clientX, ce.clientY);
    }
  });
}

// Coalesced events (right panel)
canvas.addEventListener("pointermove", (e) => {
  const coalesced = e.getCoalescedEvents();
  // coalesced.length is often 1-4; raw fires far more
  for (const ce of coalesced) drawPoint(ce.clientX, ce.clientY);
});

See also