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.
pointerrawupdate not available
This page requires a secure context (HTTPS or localhost) and Chrome 76+ for
pointerrawupdate. The left canvas has been switched to pointermove mode so you can still compare coalesced vs non-coalesced event delivery.
secure context required
pointerrawupdate is only dispatched in secure contexts (HTTPS). This page is running over HTTP. The left panel falls back to pointermove; upgrade to HTTPS or run via localhost to enable raw events.
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);
});