互換性が向上し、スムーズなタッチ操作を実現

タップにスムーズに反応してスクロールするモバイルウェブ アプリを求めています。開発は簡単ですが、モバイル ウェブブラウザがスクロール中のタッチイベントにどう反応するかは、実装の詳細として TouchEvent の仕様として残されています。そのため、アプローチは大きく 4 つのカテゴリに分類できます。このような状況は、スクロールの滑らかさの実現とデベロッパーによる制御の維持との間の基本的な緊張関係を明らかにしています。

タッチイベント処理には 4 種類のモデルがあるでしょうか。

各ブラウザの動作の違いは、4 つのモデルに大別されます。

  1. 通常の同期イベント処理

    touchmove イベントはスクロール中に送信され、スクロール更新のたびに、touchmove の処理が完了するまでブロックされます。これは、最も理解しやすく、最もパワフルですが、スクロール中の各フレームをメインスレッドでブロックする必要があるため、スクロールのパフォーマンスに悪影響を及ぼします。

    ブラウザ: Android ブラウザ(Android 4.0.4、4.3)、Mobile Safari(div のスクロール時)

  2. 非同期の touchmove 処理

    touchmove イベントはスクロール中に送信されますが、スクロールは非同期に進めることができます(スクロールの開始後は、touchmove イベントは無視されます)。その結果、イベントが「二重の処理」になることがあります。たとえば、ウェブサイトが touchmove で何かをした後もスクロールを続け、イベントで preventDefault が呼び出されて、ブラウザにその処理をするよう指示するなどです。

    ブラウザ: Mobile Safari(ドキュメントのスクロール時)、Firefox

  3. スクロール時のタップ移動の抑制

    touchmove イベントは、スクロールの開始後に送信されず、touchend イベントの後まで再開されません。このモデルでは、静止したタッチとスクロールの違いを見分けるのは困難です。

    ブラウザ: Samsung ブラウザ(マウス移動イベントが送信されました)

  4. スクロール開始時にタッチをキャンセルする

    スクロールの滑らかさとデベロッパーの制御を両方向にすることはできません。このモデルでは、ポインタ イベント仕様のセマンティクスと同様に、滑らかなスクロールとイベント処理のトレードオフを明確にできます。下にスワイプして更新するなど、指を記録する必要がある操作は使用できません。

    ブラウザ: Chrome パソコン M32 以降、Chrome Android

変更する理由

Chrome for Android は現在、Chrome の古いモデルである、スクロール開始時の touchcancel を使用しており、スクロールのパフォーマンスを高めますが、デベロッパーの混乱を招きます。特に、一部のデベロッパーは touchcancel イベントやその処理方法に気づいておらず、そのためウェブサイトが動作しなくなっています。さらに重要な点として、プルして更新、隠しバー、スナップ ポイントなど、UI スクロールの効果と動作の全クラスが適切に実装するのは困難または不可能です。

これらの効果をサポートするために特にハードコードされた機能を追加するのではなく、デベロッパーがこれらの効果を直接実装できるプラットフォーム プリミティブを追加することに重点を置いています。この理念の概要については、合理的なウェブ プラットフォームをご覧ください。

Chrome の新しいモデル: スロットリングされた非同期 Touchmove モデル

Chrome では、他のブラウザ用に作成されたコードとの互換性を高めるために新しい動作を導入します。また、スクロール時に touchmove イベントを取得することに依存する他のシナリオにも対応できるようにしました。この機能はデフォルトで有効になっています。また、chrome://flags\#touch-scrolling-mode フラグでオフにできます。

新しい動作は次のとおりです。

  • 最初の touchmove が同期的に送信され、スクロールのキャンセルが可能になります。
  • アクティブ スクロール時
    • touchmove イベントは非同期で送信される
    • throttledあたり 1 イベントにthrottledする、または CSS throttled スロップ領域を超えた場合
    • Event.cancelablefalse になっている
  • それ以外の場合は、アクティブなスクロールが終了したとき、またはスクロール制限に達したためにタップできなくなったときに、touchmove イベントが通常どおり同期的に呼び出されます。
  • タッチ終了イベントは常にユーザーが指を離したときに発生する

Chrome for Android でこのデモを試し、chrome://flags\#touch-scrolling-mode フラグを切り替えて違いを確認できます。

ご意見をお寄せください

非同期 Touchmove モデルは、ブラウザ間の互換性が向上し、新しいクラスのタップ操作効果を実現できる可能性があります。Google は、デベロッパーの意見に耳を傾け、それを使用して何ができるのかを知りたいと考えます。