Latency is rarely the problem

When a touch control feels unresponsive, the instinct is to look for latency. That is usually the wrong place.

Modern browsers deliver a pointerdown event within a frame or two of the touch. Unless the game is doing heavy work per frame, the input path is not the bottleneck.

What produces the feeling of unresponsiveness is almost always one of four things: a control that sticks, a browser gesture intercepting the input, a target too small to hit reliably, or a delay the page itself introduced.

Stop the browser interfering

Touchscreens have default behaviours that actively fight a game, and each needs disabling explicitly.

  • touch-action: none on the canvas, so a drag is not interpreted as a scroll
  • touch-action: manipulation on buttons, so a double-tap does not zoom
  • -webkit-tap-highlight-color: transparent, so taps do not flash a grey box
  • user-select: none on the control strip, so a long press does not start selecting text
  • preventDefault on pointerdown for the canvas, so the page does not pan

None of this is visible when it works and all of it is obvious when it is missing. It is the single highest-value hour of work in making a browser game feel native on a phone.

Pointer capture stops sticking

The most common touch bug in browser games: press a button, slide your finger off it, release, and the game still thinks it is held.

It happens because the release event fires on whatever element the finger is over, not the one it started on. The element that got pointerdown never hears about the release.

Two fixes together make it robust. Pointer capture makes the originating element claim subsequent events for that pointer, and explicit release handlers on pointercancel and pointerleave cover the cases capture does not.

Size targets for fingers

A control sized for a mouse cursor is not reliably hittable with a thumb, particularly in motion.

Every touch button on this site is at least sixty-two pixels tall, which is comfortably above common accessibility minimums and sized for a thumb rather than a fingertip.

Spacing matters as much as size. Adjacent controls need enough gap that a slightly misplaced press hits nothing rather than hitting the wrong thing — particularly for a pair like left and right, where the wrong one is worse than none.

Never put controls over the playfield

Floating controls over the game saves vertical space and costs more than it saves.

A control drawn over the playfield covers the thing the player needs to see, and in a game where the ball's position is the entire information channel that is unacceptable.

It also creates the possibility of a mis-tap landing on something else. Keeping interactive elements in a dedicated strip beneath the game means nothing interactive is ever near content — including advertising, which must never be adjacent to a control.

Make drag feel direct

Drag control maps the finger's position onto the paddle's position rather than moving the paddle by the distance the finger moved.

Absolute mapping is what makes it feel direct: the paddle is where your thumb is, which requires no mental translation. Relative mapping, as a trackpad uses, always feels like driving something rather than holding it.

The one constraint is that the paddle is still limited by its own speed, so a fast swipe cannot teleport the blade. That keeps drag and keyboard equivalent in capability, which matters because both are available at once.

Keep the frame budget honest

A control that is correctly implemented can still feel bad if the game is dropping frames, because the visible response to an input is delayed by however long the frame takes.

The two largest levers on a phone are capping the device pixel ratio at two — beyond which sharpness is imperceptible while fill cost grows with the square — and pooling objects so garbage collection never pauses mid-rally.

Running the simulation at a fixed step and rendering once per frame also means a device managing thirty frames a second gets identical physics, so a slow phone is choppier but not harder.

Key takeaways

  • Unresponsive touch controls are usually sticking, intercepted or mis-sized rather than slow.
  • Disable touch-action, tap highlight and selection explicitly; none of it is default.
  • Pointer capture plus explicit release on cancel and leave is what stops controls sticking.
  • Targets at least sixty-two pixels tall with real spacing between adjacent controls.
  • Absolute drag mapping feels direct; relative mapping always feels like driving something.

Frequently asked questions

Why do my touch buttons stick down?

Because the release event fires on whatever element the finger is over rather than the one it started on. Use pointer capture and add explicit release handlers for pointercancel and pointerleave.

How large should a touch target be?

At least sixty-two pixels in the direction of travel, with real spacing between adjacent controls so a slightly misplaced press hits nothing rather than the wrong thing.

Should controls overlay the game to save space?

No. A control over the playfield covers information the player needs and creates mis-tap risk. A dedicated strip beneath the game costs space and is worth it.

Is drag or are buttons more responsive?

Both are equally fast. Drag feels more direct because the mapping is absolute; buttons are more precise because a single large target is easier to hit reliably than a gesture.

References and further reading

  1. MDN Web Docs — Pointer events
  2. W3C — WCAG 2.2 quick reference
  3. web.dev — Core Web Vitals