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