Code

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 だけ書いてください。これは速くなります。

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

0 件のコメント:

コメントを投稿