Send touchcancel when scrolling starts?

Hey guys,
The touch events specification leaves the decision to dispatch a
touchcancel to an implementation detail (
http://www.w3.org/TR/touch-events/#the-touchcancel-event), and we have one
key way implementations differ today that's causing some pain: what happens
on scroll.

Today Chrome Android sends a touchcancel as soon as scrolling starts (and
then no further touch events for the scroll).  The idea is that they're
trying as hard as possible to have smooth scrolling (often on the GPU
thread), and avoiding blocking each scroll frame on the main thread (and JS
handlers) is a huge perf win in practice.

This is similar to the behavior on mobile safari when scrolling the
document or other -webkit-overflow-scrolling: touch element.  Except there
they just silently swallow the touchmove events and send touchend when the
finger lifts (and they only do it when scrolling/overscroll actually
happens, where Chrome does it for any scroll gesture regardless of the
content).  The Chrome Android team got feedback from applications that it
was important to know immediately when touch events were no longer being
dispatched rather than have them silently lost, hence the use of
touchcancel.

In contrast, Firefox, Chrome deskop, and mobile safari on divs with
-webkit-overflow-scrolling:auto all behave in the simpler but slower
fashion.  Each scroll frame is blocked on the touchmove event, and calling
preventDefault on any touchMove can temporarily stop the scroll.  This is
certainly best for compatibility and gives the site the most control, but
it's terrible for scrolling performance (which we know is critical to
engagement).  Sites seem to often have unnecessary touch handlers (eg. due
to a desire to use event delegation) and people don't realize how it
contributes to scroll jank.

We've decided we're going to switch Chrome desktop to follow the Chrome
Android model of using touchcancel here (crbug.com/240735).  I don't yet
have any exact numbers on the difference it makes to scrolling performance
in practice, but we plan to add some metrics so we can measure it as part
of our switch - I'll try to share those numbers with you.  This model is
also consistent with the pointer events design (where scrolling and events
are always mutually exclusive), and potentially a pre-requisite to
implementing touch-action in a way that's compatible with pointer events.

The other benefit of requiring developers to be explicit about when they
intend to suppress touch scrolling is that it allows the browser to add
overscroll gestures without having them break existing websites.  Eg. on
ChromeOS we recently added swipe left or right to go forward/back.  We've
found a couple web sites that are processing touch events and just assuming
that scrolling isn't possible and so aren't calling preventDefault to stop
the scroll.  So even without making the touchcancel change, these websites
will be broken.  We're trying to encourage developers to call
preventDefault on touch events they handle (eg. see my Google I/O talk:
https://developers.google.com/events/io/sessions/361772634), but we're
still running into sites that have been tested, for example, only on Safari
and Firefox and so are broken on Chrome.

Of course touch-action from pointer events makes this much clearer and
explicit - I think we all agree that's the right long-term path forward.

In the shorter term is there any chance that the Firefox implementation may
change to also send touchcancel when scrolling?

Thanks,
   Rick

Received on Friday, 7 June 2013 15:41:02 UTC