2013/10/27

「1秒でも早く申し込みたい!」を可能にしたGoogle Chromeの工夫

近年スマホを使う理由として、「Webが見やすいから」というのがトップにランクインしている。
就活生たちをみていても「いち早くシューカツサイトで説明会の申し込むために」スマホを購入した、という学生も少なくない。

しかし、「いち早くシューカツサイトで説明会の申し込み」をするのに、
じつは利用するブラウザによって5秒ほど差をつけられてしまう、という事実に気づいているだろうか?おそらくほとんどの人は気がついていないだろう。

仕組みから説明してしまうと長くなってしまうので、結論から言うと、
・Androidの標準ブラウザ、iPhoneのSafariは、Google Chromeよりも「タップ」の判定時間が300ミリ秒遅い
のである。

以下、その仕掛けをひもといていこう。


①「300ミリ秒遅い」を体感しよう

普段使いしていると、通信遅延のほうが大きいし、はっきりいって300ミリ秒くらいの遅延は気が付かないと思う。
それでも、以下のような手順をやってみると「あれ、意外と300ミリ秒って長いかも」という実感が生まれてくると思う。まずはそれを自分の手で確かめていただきたい。
(いまのところ、私が確認しているのはiPhone 4SとAndroid 4.2だけです。その他の環境だとうまくいかないかもしれません・・・)

・まずはGoogleChromeをインストールしましょう。


・とりあえずYahoo! Japanのトップページへ…
べつにどこのサイトでもいいのですが、Yahooでも見ましょう。
で、てきとうにここ↓をいつものようにタップしてみてください。



・次に、「設定」→「ユーザ補助」→「強制的にズームを有効にする」にチェックをつけて、再度Yahooのリンクをタップしてみよう

  


さて、違いがわかりましたか?

わからない、という人は、もう一度チェックを外して/つけて、
タップする際に、じっくりタップするのではなく、パッと画面を叩く程度に軽いタップをするように意識してやってみてください。

もうめんどくさい、という方のために、動画をとってみました。(最初から見せろよ、というツッコミはナシでw)
(0:00付近と0:23付近をよーく見比べてみてください)


わかりましたか?リンクが青く反転するまでの時間(=タップの判定がされるまでの時間)が"なんとなく"違いますね?
その"なんとなく"の違いこそが、説明は後述しますが、300ミリ秒の違いなんです。


②なぜ300ミリ秒おそいの?

どうしてGoogle Chromeが300ミリ秒早いの?を知るには、
そもそもなぜ「300ミリ秒遅いの?」という理由を知る必要があります。
そして理由は意外と単純で、さきほど触っていただいた「強制的にズームを有効にする」と関係があります。

これも結論から言うと、ダブルタップかシングルタップかを判定するために300ミリ秒が必要なのです。

AndroidやiPhone端末は、ブラウザ画面でダブルタップすると拡大しますね。
もう少し専門用語で言うと、WebViewはブラウザに対して「シングルタップが2回」なのか「ダブルタップ」なのかを判別した上で、イベントハンドラをコールバックしないといけないわけです。


●ダブルタップ
-----------↓-↑----↓--↑-----------------

●シングルタップが2回
---↓---↑----------------------↓--↑-----


Android標準ブラウザでは、「シングルタップが2回」なのか「ダブルタップ」なのかは、
上の模式図でしめしたところの ↑(1回目のTouchUp)から ↓(2回目のTouchDown)まで
 300ミリ秒以内 →ダブルタップと認識する
 300ミリ秒以上 →シングルタップが2回と認識する
となっています。

こちらも専門用語で言うと、↑(1回目のTouchUp)が来て、300ミリ秒待ってみて
 その間に↓(TouchDown)が来れば「ダブルタップ」をコールバック
 その間に↓(TouchDown)が来なければ「シングルタップ」をコールバック
します。

さらに詳しく、ソースコードでいうと、

frameworks/base/core/java/android/webkit/WebViewInputDispatcher.java
    448 
    449     private void scheduleClickLocked() {
    450         unscheduleClickLocked();
    451         mPostClickScheduled = true;
    452         mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_CLICK, DOUBLE_TAP_TIMEOUT);
    453     }
    454 
    455     private void unscheduleClickLocked() {
    456         if (mPostClickScheduled) {
    457             mPostClickScheduled = false;
    458             mUiHandler.removeMessages(UiHandler.MSG_CLICK);
    459         }
    460     }

452行目のDOUBLE_TAP_TIMEOUTこそが、300ミリ秒という値です。

frameworks/base/core/java/android/view/ViewConfiguration.java
     92     /**
     93      * Defines the duration in milliseconds between the first tap's up event and
     94      * the second tap's down event for an interaction to be considered a
     95      * double-tap.
     96      */
     97     private static final int DOUBLE_TAP_TIMEOUT = 300;

scheduleClickLockedとunscheduleClickLockedの呼び元を見ると、ざっくり前述の説明のような条件分岐で、ダブルタップかシングルタップかを判定しているのがわかるかと思います。(気になる人は調べてみてください)


③なぜGoogle Chromeは300ミリ秒の待ちをなくすことができたの?

さて、Google Chromeの工夫を説明する準備が整いました。

前述の通り、普通の発想では
 300ミリ秒以内 →ダブルタップと認識する
 300ミリ秒以上 →シングルタップが2回と認識する
という条件分岐があることから、300ミリ秒待たないという選択肢は無いように見えます。

では、Google Chromeは一体どのようにしてこの300ミリ秒をなくしたのでしょうか?

実は答えはすでにここまでで書いています。

そう、Google Chromeは2つの点に着目しました。
(※あくまで私の予想なので、もっとあるかもしれません…他にも工夫点を見つけられたら教えてくださいw)

・そもそも拡大する必要のあるページなのか
  →拡大が禁止されているページでは、ダブルタップ操作は不要なので、すべてシングルタップ判定をさせればいい!そうすれば300ミリ秒またなくてもいい!
    →だから、「強制的にズームを有効にする」のOn/Offで300ミリ秒遅いかどうかの挙動が変わったのです。

・ダブルタップかどうかを↑(1回目のTouchUp)時点でできるだけ判定できないか
  → ↓(1回目のTouchDown)から↑(1回目のTouchUp)まで"じっくり"タップした場合は高確率でダブルタップではない。そうすれば、300ミリ秒またなくても、↑(1回目のTouchUp)ですぐにシングルタップ判定を出せる!
    →だから、「強制的にズームを有効にする」にチェックがついていても"じっくり"タップしている人にとっては300ミリ秒遅いことは体感しにくい、と前述していたのです。


意外と単純ですね。


●最後に・・・

ここまで読んでくださった読者には、少しだけいいことを教えましょう。

冒頭でAndroid標準ブラウザは300ミリ秒遅いって書いてしまいましたが、
実は遅くない端末がいくつか有ります。

私が確認した限りでは
・Xperia AX SC-01E
・REGZA Phone T-02D
・Arrows NX F-06E, F-01F

自分がFの中の人なので、Fの端末が多くてすみません。多分他にもあるでしょう。

これらの製品はAOSPそのものではなく、チップベンダーがカスタマイズしてきたAndroidソースをベースに作られているので、実は彼らがChromeの仕組みを知っていてこっそりと改良を入れて出してきているのかもしれません。

「タップが早くできるから端末を買おう」だなんて人はいないと思います。
でも、こういうカタログスペックに見えない所で「使っていて"なんとなく"気持ちがいい」というユーザの使用感の向上のために日々努力している人がいることも確かです。

今回、Chromeの挙動を調べてみて、自分も同じ開発者として、そういう一員でありたいなと思った次第でした。