Code

ラベル Android の投稿を表示しています。 すべての投稿を表示
ラベル Android の投稿を表示しています。 すべての投稿を表示

2015年3月29日日曜日

モバイル Click イベント遅延

 今週、開発したプロジェクトのリリースがありました。その中の一つの改善ポイントはモバイルでの Click を早くすることです。モバイルなら、Touch イベントが追加されて、指をタッチパネルに触れた瞬間 TouchStart が発生します。そのあと、 TouchMove と TouchEnd, 次に Mouse から継承された MouseMove などが発生して、さらに、そのあと Click が発生します。主に、ダブルタッチを検知するために Click を遅らせたことです。一般的にこの遅延は 300 milliseconds と言われています。自分で試したところ、320-350 ぐらいでした。
 これを解決するためには、TouchEnd の後に、すぐ自分で Click イベントをトリッガーすればいいです。ただし、そのあとシステムの Click を抑制する必要があります。これをプロダクトで使えるライブラリは幾つかあります。今回ちょっと修正して、使ったのは fastclick です。基本的には機能が十分ですが、少しコードを参考にして、うちのサイトにあった軽量のライブラリを作りました。
 実際その 300 milliseconds を感じるサンプルも提供されています。
http://ftlabs.github.io/fastclick/examples/layer.html

 Android Chrome ブラウザーの一部がすでに改良されて、viewport を探知したら、Click イベントは早めにトリッガーする仕組みがすでにありましたので、fastclick ではそれをチェックして、もしすでにあったら、何もしないことになります。
 iOS で開くと、改良版とnative の click を使ったバージョンの区別がすぐわかります。ぜひ上記のリンクを iPhone などで開いて、クリックしてみてください。
 他には hammer.js と polymer gesture があります。ploymer gesture は ploymer のライブラリですが、基本的に stand along で使えるものです。
 
 将来 Windows Phone がもう少し普及したら、Xmarine や HTML5 Web App がさらに有利になりますので、Native なみの User Experience を実現するには、この遅延をなくすことは大事です。
 それでは。

2014年10月18日土曜日

Android WebView の 動画が遅い件

 先日、新しい Ads のパフォーマンスが良くないなと思っただけで、今日は他のチームも発見して、相談されました。具体的には WebView を使って、HTML ファイルを表示してますが、画像では iOS, Android 両方問題なく、良く表示されてますが、動画の場合、ある Android 機器が超遅くて、遅くて、使い物になれないほどです。
 実際、Web Inspect で見てみると、JS の実行が遅いです。じゃ、 CSS ではどうでしょうと思って、ほぼすべてのコードを書き換えて、CSS でアニメーションを実現して、試しました。。。でも、遅いです。。。CSSの場合、ハードウェアの加速があるので、速いと言われていますが、Android ではそうではないそうです。まぁ、機器のスペクもよるので、Nexus 5 で試しましたが、iOS ほどスムーズではないですが、そこそこ動いています。
 こう見ると、多分古い Android 機器はだめみたいです。。。何でだろうと思って、やはり WebView はブラウザーより遅くて、開発時は注意しないと。
 一応メモして、将来何か参考になるかもしれないです。
 それでは。

2014年5月6日火曜日

Android WebView 謎。。。

 最近、HTML5 Ads ページのバグが報告されました:Android の WebView で全ページ表示できない。。。
 本来なら、スクロールバーが表示されるので、問題がないでしょうと思っていました。ただ、営業の方達はぜひ全ページを表示できるようにと。
 以前は JS で設定し直す手段で Ads を正しく表示できるようにしましたが、原因がわからなくて、未だに調査中です。。。また今回のバグが出てきました。。。 orz
 ただ、iOS では Ads の表示が正しいと。多分 Android は Webkit をベースにしていますが、 WebView の実装が iOS と比べると、まだまだ W3C の標準になってないでしょう。また、各要素のデフォルト margin, padding がブラウザの設定が違うでしょう。
 そうすると、iOS では正しく表示できているので、 Android の開発者に依頼して、WebView の設定を調べてみようと。20分で、setInitialScale(1) をコメントアウトしたら、iOS と同様に表示できたとの連絡が来ました。。。
 一応 Ads ページの中に、viewport がちゃんと設定しているし、なぜ setInitialScale をもう一度呼び出すか、デフォルト値はなにになっているか、ページ中の Viewport ではだめですかとかいろいろ質問がありましたけど。今週中に Android バージョンが公開されますので、後回しにしました。
 自分は設定する必要がないと思いました。後日、詳細を調べてみよう。

 また、アンドロイドディバイスのサイズが本当にいろいろあって、media query で Responsive レイアウトをスタイリングする時、実際のディバイスが確認するようと。たまにはシミュレータとディバイスとブラウザリサイズの表示が異なります。実機で確認するのは不可欠です。
 
 早めにリリースできるように。:)
 それでは。

2014年5月1日木曜日

アンドロイドの WebView CSS Refresh問題 <= JSで再度設定し直す。原因調査中。。。

 ニュージーランドに旅行に行きました。:)しばらく更新してないから、いろんなものを忘れないうちに、メモしておこう。
 今日アンドロイド Phone サイズの対応作業がありました。基本的に Media Query を使いますが、たまには HTML の書き方に疑問を持つようになりました。なぜなら、最初 Web Page を作るとき、Tablet を想定してから、Phone サイズになると、文字のサイズや、本来なら絶対2行にならないところが切れたりして、ちょっと対応しにくかったです。幸いコンセプトが違うから、矢印などいらない部分を全部隠して、2時間で作業をほぼ完了しました。
 ただ、 広告ページを対応するとき、iPhone では綺麗に表示できたのに、アンドロイドでどうしてもうまくいかないことがありました。CSS で写真の高さを 100% 設定しても、スクロールバーが出るし、押してしばらくすると、スクロールバーが動けるようになりました。原因はわからない。。。
 基本的にアンドロイドとiPhone は WebKit をベースにしているから、表示も同じのはずですが。まぁ、基本的にデフォルトのスタイルがちょっと違ったりしていますけど。意外にアンドロイドの WebView 使いにくいなと感じました。
 それで、setTimeout を使って、ある程度遅延を入れて、再度 CSS を設定し直したら、うまく行きました。
 Android 4.4 Chrome での表示は正しいですけど。。。
 何でだろうね。明日時間があったら、見てみよう。。。

2014年3月19日水曜日

モバイル Web App が遅い ??

Update: iOS 8 から UIWebView のウップグレードとして、WKWebView が追加されました。Nitro も使えるようになりましたので、in App WebView がさらに速くなりました。

最近面白い記事を二つ読みました。一つはなぜ Mobile Web App が遅いか
        why mobile web apps are slow
 もうひとつは遅くても、ちゃんと開発すれば、全然感じられないほど速い。
        the making of fastbook an html5 love story

 ネーテブの App と比べると、Web App が遅いのは当然、ただ何所まで遅くなるかはみんなわからない。それで、いろんな文章が出て来た。読んだ文章は結構データも充実しているので、信頼できるでしょう。ただ、ネーテブコードでも遅くなるケースも結構あるので、これは開発者次第です。
 そうすると、Facebook App をSencha を使って、開発すると、ネーテブとほぼ同じ、またはもっと速いよとの文章です。
 実際コードを読んでみると、HTML5 は遅いかもしれませんが、まさしく Sencha のように、よく作ると、あまり感じられません。
 じゃ、Web App を作るとき、何を注意すべきでしょう:
・まず、DOM 操作が遅いから、できるだけ減らしましょう。DOM 操作というのは HTML Element を作成して、その後、append, before などの関数でそれを挿入すること。DOM ツリーが更新されるので、時間がかかります。特に、IE7, IE8 の時代、JavaScript 自体が遅いし、大量のノードを挿入すると、メインプロセスが止まって、無応答になります。
・できるだけ、文字列で HTML 文を作って、一気にDOM にいれましょう。これは .innerHtml を使います。これは Mustache や、 Handlebars と言ったテンプレートライブラリの用途です。もし、小さいものならば、 underscore.js も template 関数があるので、それを使ってもいいでしょう。
・resize, scroll などにバンドルするハンドラ関数を throttle や debounce 関数を使って、実行の回数を減らしましょう。scroll すると、一瞬にかなりの数のハンドラ関数が呼ばれますので、かなり負荷が高いです。ある時間を経過後、ハンドラを呼べばいいでしょう。
・setTimeout を有効に使いましょう。setTimeout(func, 0) の意味は JavaScript のコールスタックが空になったら、 func を実行するのです。元々注意すべきところは setTimeout は何時実行されるかは不明ですので、ある程度の時間を経過したらというのです。例えば、いっぱい HTML 文字列を挿入して、挿入後、 Focus を新しく生成した Input に設定する処理では、何時挿入が完成するかはわからないので、その後で setTimeout 0を設定すると、挿入完了したら、実行されます。
・DOM の Event Propagation を有効に利用しましょう。例えば、li タグ中の div にハンドラ関数をバインドしたい場合、li の親の ul にバインドすれば、event.target でクリックした要素が取得できますので、一つのハンドラですむのです。li にいっぱいハンドラ関数をバインドすると、結構コストがあります。
・ロードするライブラリを注意しましょう。いつどのようなライブラリがロードされるかちゃんと管理しましょう。本来なら require.js がこういう仕事のためですが、自分はそのライブラリちょっと気に入らないので、使いたくないです。ライブラリをロードするにはかなりコストがありますので、最小限のコードを実行しましょう。例えば zeptojs を使ったりしてしましょう。まぁ、本当に速くしたいなら、自分で自分用のライブラリを作りましょう。そうすると、エラー処理とか省略できるので、かなり速くなります。自作の場合、jsperf.com がかなり良くできています。使ってみてください。
・写真のロードや、ファイルのサイズ、後キャッシングするかどうかもかなり影響しますので、注意しましょう。
 - まず写真について。現在のブラウザは写真をロードするには複数のスレッドを使っていますので、二つのドメインからロードすればいいです。そうすると、Static のリソースは別々のドメインに保存すればいいです。
 - 次ぎ、ファイルのサイズについて。ファイルの請求はかなり時間がかかりますので、jsや、cssファイルを一つのファイルにまとめて、不要なスペース、改行を全部削除しましょう。 Ruby や、Node.js にいろんなツールがあるから、有効に使いましょう。RoR の Asset Pipeline はかなり良くできてますので、使えるなら、使いましょう。
 - キャッシングについて。もし一つのファイルは変更する予定がないなら、expire 日付を一年以降に設定したりして、ロードは最初の一回のみでいいでしょう。RoR ではファイル名の後に SH 列があるので、内容が変更したら、その文字列も変わるので、かなり便利です。
・HTML5 の新しいフェーチャーを使いましょう。
 - Local Storage を使いましょう。Cookie が送信されるので、サイズを累計すると、かなり大きくなります。だから、必要なときだけ、データをロードして、送信しましょう。
 - Offline 機能を有効に使いましょう。これはキャッシングと同じような感じですが、 Offline 機能を使うと、どのファイルをどう更新するかは自分でコントロールできます。
 - 動画なら、CSS を使いましょう。JS の fadeIn, fadeOut 関数などはかなりCPU 使いますので、良くないです。 CSS だと、GPU を使って、画像が作られますから、ブラウザの負担た小さいです。
・ CSS についても注意しましょう。できるだけ、div .cls1 .cls2 {} のようなものを書かないでください。これはブラウザが CSS を適用する際に、.cls2 から、要素すべての親をスキャンして、div .cls1 となっているかどうかチェックするから、時間がかかります。できれば、.cls2 だけ書いてください。これは速くなります。

まぁ、他にもいろいろありますけど、後日また追加します。
それでは。