Code

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

2014年11月9日日曜日

ローカル Web App : AngularJS + ExpressJS + Node.js

 先週、検証チームから依頼があって、protractor を UI で動くようにしたいと。確かに、コマンドラインはちょっと使いづらいので。慣れてる人は、それでいいかもしれないけど、テスターはやはり、もうちょっとビジュアル的な UI や、テストケースレポートが欲しがるようです。
 いろいろ考えてみると、protractor も Node.js で動かしているので、そのまま Node を使えるなら、HTML 5 の Web App を作れば、簡単に UI ができるし、NodeJS の力を使って、コマンドラインを実行すれば、早くできると思われました。
 実際調べて見たら、Express.js と Hapi.js みたいなライブラリーがあって、web server もすぐ立てられそうです。また将来、コードをそのまま使って、どこかのサーバに置いたら、同じ UI で、すぐ Online できるので、メリットが大きいです。
 それで、AngularJS を Front End で、Express.js を Back End にして、ツールを作ることになりました。インストールは npm で済ませて、Yeoman, bower で AngularJS のアップを作って、grunt でビルドなども立てて、すぐ開発に入りました。
 Express.js に generator がついてるので、それを使って、Back End のアプリも簡単に立ち上がりました。
    $ npm install express-generator -g
  $ express myapp
  下記のフォルダストラクチャーができました。app.js に path に基づいて、get, post などを書けば簡単には response 作れるようになります。static ファイルを front end に送るには、 sendfi le 関数を使えば、protractor のテスト結果レポートも簡単に Front End で表示できる。
.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.jade
    ├── index.jade
    └── layout.jade

7 directories, 9 files

さらに、もし興味があれば、 MEAN.js というライブラリがあるので
mean.js
MangoDBをデータベースとして、フル JavaScript のアプリも簡単につくれます。
Meteor も有名です。そのまま iPhone, Android アプリも作れるので、どんどん良くなっています。

それでは。

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

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

2013年12月15日日曜日

Web App : Event driven デザイン、ほかいろいろ

 JavaScript という言語は Event Driven です。マウスでウェブページをクリックすると、 click イベントが発生します。ブラウザは各イベントキャプチャーして、各要素にバインドしたイベントハンドラを呼び出します。イベントハンドラにわれわれは DOM 要素や CSS クラスを追加したり、外したりすること、ウェブページが動的になります。
 これは一般的な Web App のデザインです。それで、jQuery(document).ready(function() {}) みたいな関数が大変重要になります。なぜなら、ブラウザが HTML をパースしている間、クローズタグを終える前に、JavaScript でその中の要素を操作すると、エラーになって、ウェブページも変な形になります。このようなエラーはよく IE で見かけます。
 (実は jQuery ready 関数が onLoad などの Native 関数のラッパーだけです。いろんなブラウザ実装が違うため、最後にいつウェブページがロード終わったかちょっと違います。このような違いがなくすことで、私たちは一つのコードすべてのブラウザを対応できるようになります。Selector 機能と同じように、Cross browser も jQuery の一つ大きな特徴です。)
 このような Web App は簡単に設計できます:
一般的に、HTML を書いて、CSS クラスで色や display 属性を定義して、ready() 関数に対象の DOM 要素に初期化処理やイベントハンドラを定義することだけです。例えば:
<!DOCTYPE HTML>
<HTML>
  <HEAD>
    <script>
       $(document).ready(function() {
              // DOM のロードが終わったら、すべてのボタンと A tag に click イベント
              // ハンドラをバンドします。
             $('button, a').click(function(event) { console.log($(event.target).tagName); }
        });
    </script>
  </HEAD>
  <BODY>
    Sample です。
     <button type = "button" value="Hello"></button>
     <a href="#">Link</a>
  </BODY>
</HTML>

 ただ、このような Web App メンテナンスはちょっと大変です。なぜなら、他の開発者は「この機能はどのように実装したか」を探し出すことが面倒ですし、イベントハンドラはそう簡単に見つからないこともよくあります。JavaScript の特徴で、ただの検索だけで、見つからない可能性が十分あります。
 あと、すべての要素は一つのコードでコントロールできるので、その一行のコードを見つかるには、ちょっと時間がかかるかもしれません。
 もう一つの問題は HTML には状態など記録する機能は従来ないので、CSS や属性などを我々直接操作するしかありません。
 このような問題を解決するために、いろんなライブラリが出てきました。逆に、Event Driven もいいところが結構ありまして、これもnode.js 売りになっています:ブロックがないから、サーバーとかはいつでも、莫大なリクエストが処理できるようになります。

 knockout.js などちょっとしたライブラリの着目点もここにあります。HTML に自ら定義した属性を追加して、イベントハンドラや、初期化などのコードを HTML で見えるようになります。
 次に Backbone.js, AngularJS, Ember.js など MV* Framework が他の道で Web App の開発を簡単にできるようにします。
 だから、Frame work を使おう。:) 世界が綺麗になります。