Code

2015年12月21日月曜日

React.js Vs AngularJS、どっちがいい その2

アップデート 2016/05/22: AngularJS 1.0 に比べたら、React.js のほうがいいです。React.js は UI View のライブラリなので、AngularJS 2.0 と Aurelia と比べるにはちょっと弱いですが、性能重視なら、React.js を使ったほうがオススメです。
 
 先月から、つい新しいプロジェクトが始まって、React.js を毎日使うようになりました。開発してるページは結構複雑なウェブアップで、Back End は ASP.NET C# WebApi を使って、Ajax でデータを取得してから、すべてのロジックは Client サイドにあります。
 今全てのページも一つの App にして、実際レンダリングは JavaScript になっています。それも React.js の哲学の一つ:DOM は遅い、JavaScript は格段に速い。あと、AngularJS のテンプレートと違って、Component が JSX で JS コードで直接 HTML をコントロールしています。
 JS コードだから、何をやろうとすると、結構やりやすいです、テープレートに比べたら。ただ、JSX を普通の JS コードに変更するにはちょっと時間がかかります。今 WebPack と Babel を使っています。Gulp Watch を使って、JSLint も含めて、コンパイルは約 3 秒ぐらいかかります。これは遅いと感じています。AngularJS の場合、コンパイルが必要ないから、スタイリングするとき、やりやすいです。WebPack を通すと、ちょっと時間がかかるため、Watch をうまく使わないと、開発効率が下がります。今、Gulp のタスクをさらに細かくにして、コンパイル時間を1秒いかに抑えたいです。ここで、AngularJS の開発効率は高いと思います。

 次は Flux という Framework です。AngularJS の場合、テンプレートから、Service まですべての MV* を提供しています。React.js は UI Library だから、Flux とうまく合わせて、一つの Framework になります。Flux は結構簡単なもので、何かをやろうとすると、AngularJS と比べたら、やりにくく感じます。ただ、Flux は簡単ゆえに、アプリ全体の構造も簡単になります。AngularJS みたいに、2ヶ月ぐらい勉強時間と比べたら、React.js のほうが勉強しやすいし、強制的に簡単なアプリ作れます。ここで、React.js がいいなと思います。AngularJS の機能は時々複雑すぎて、理解するには時間がかかります。

 最後パフォーマンスについて。どんな Framework を使っても、それなりのコストが発生します。勉強時間とか、Framework のロード時間とかいろいろ。ただ、Framework を使うと、開発の効率も向上するし、Unit Tests と End-2-End Tests のツールも簡単に使えるようになります。そこは総合的に考慮しなければなりません。
これがいいですね: The Cost of Frameworks
 自分の感じでは、React.js は 3-4 倍ぐらい、AngularJS より速いです。DOM のレンダリングスピードがそこまで速いと感じたら、AngularJS 好きな私も、さすがに考えます。100ms の React.js と 300ms の AngularJSの差、200 ms は大きいです、End user の視点から見ると。
 ただ、React.js も万能じゃないので、Virtual DOM のツリーを毎回比べるので、App が大きくなると、遅くなります。
 React のパフォーマンス

 隣のチームでは AngularJS と React.js を同じプロジェクトに使おうとしていますが、Architect が反対しているそうです。理由として、二つの技術を混ぜたくないです。将来メンテナンスに難があると考えてるでしょう。。。私は両方をうまく使い分けしたほうがいいと思って、混ぜるのが賛成ですけど。

 今、私に AngularJS と React.js どっちがいいと聞かれると、アプリの性質や、開発期間とかによって、両方を使いたいなと思います。。。
 個人的には React.js の Component が AngularJS の Directive より使い易いと思います。もし会社全体的に React.js を使うなら、WebPack を使って、Component を充実したら、AngularJS より使い易いと思います。

AngularJS 2.0 も Lazy Loading などできたら、どっちを使うかまた悩むところです。。。

 あ、もう一つ、現在 AngularJS のライブラリが多くて、成熟していますが、React.js の場合、まだまだ発展途中で、NPM からインストールした Component にはバグがあったり、機能面ちょっと足りなかったり部分があります。もし、複雑な Web App を開発するなら、AngularJS のほうがいいかもしれません。

 まぁ、後日経験を積んで、また比べましょう。

追伸: React.js には isomorphic 機能がサポートしています。いわゆる、サーバー側もクライアント側も同じコードで Web App をレンダリングできます。つまり、サーバー側も同じ JS コードで、まず Web App の HTML をレンダリングして、その HTML コードがクライアント側でロードして、同じ JS コードを実行すると、イベントハンドラーや、ルートなども初期化して、Web App が動くようになります。これは Web App のロードスピードをかなり加速できます。
 サーバー側、Node.js を使うなら、簡単にできますが、Facebook がいろんな言語を対応しているそうです。こちら ASP.NET バージョンです:
 reactjs.net

 今のプロジェクトでは、isomorphic 使ってないので、来年早々やってみようと思っています。
 では、また。

2015年11月8日日曜日

Ract.js 概念から

 最近、他のプロジェクトが忙しくて、短期的に助けに行きました。今、そのチームは Home Loan Calculator を作っています。会社初めての React.js を使う Web App です。最初の二日間はソースコードを読んでん、Gulp タスク、 WebPack を慣れるだけでした。
 AngularJS より、React.js のほうが簡単でした。Component の概念をわかったら、もうだいぶどのように HTML をレンダリングするかをイメージできるようになりました。
 まず、React.js はただの UI ライブラリです。MVC 中の V または C-V だけです。まぁ、全て Component に Event Handler などを書けば、普通の Web App になるだけ。Reuse の観点から、やはりM(Model)をあったほうがいいです。その C-V と M の間に座るのは Facebook は Dispatcher というものを勧めています。下記のサイトは詳しく紹介しています。
Flux アーキテクチャー

 React.js は App をレンダリングには Virtual Dom というものを内部で持っています。DOM 操作をする前に、次なる状態 (props, state) を使って、現在の Virtual DOM をまず比べます。その結果を基づいて、DOM 更新を行います。ここのフィロソフィーは JavaScript は DOM 操作よりかなり速いです。そうすると、Web App 全体が速く実行できます。自分で使ってみたら、Chrome のパフォーマンスツールによると、多分4倍ぐらい React.js ほうが速いです。(React.js 300ms - AngularJS 1300ms)まぁ、Web App の性質にもよりますけど。
 また、 UI ライブラリとして、 React.js も Component の状態をコントロールするために、lifecycle 細かく複数のコールバック関数を分けています。下記のサイトをご参考を。
component specs, lifecycle

 Flux を使うと、AngularJS と比べたら、機能をどのように入れるかの設計フェーズはちょっと難しいです。ng-controller, service みたいの概念がないから、例えば、Ajax call はどこに入れるかと考えると Action にするか、data store に入れるか、または Component に入れる。。。いろいろ選択しがありますが、今のアプリでは action に入れています。success の call back に Dispatcher を使って、Store をアップデートしてから、その store の中から、Change event を Emit して、UI (Component) を更新するようになっています。

 アプリ全体の設計も AngularJS と違って、まず App という体制を作って、その App の中には Header, Inputs, Results, Footer などの Component 入れます。各 Component もさらに細かい、小さい Component を持っています。これをベースに、React.js は Virtual DOM を作ります。
 Component は props (properties)、と state が持っています。props は親の App から、attributes に設定したものです。state は component 自分でメインテナンスします。props と state を変わると、React.js は自動的に Render() function を呼び出して、DOM の再レンダリングします。

 具体的に、どのように動くかは後日また詳しく。

2015年10月10日土曜日

ASP.NET C# MVC4 に Webapi アップデート

 先日、あるプロジェクトを ASP.NET C# Web MVC4 から Web Api に直そうと。以前、MVC4 のプロジェクトでも幾つかの Controller が Json を返しています。それで、今回の機に、もう Web Page を他のプロジェクトに移して、この App との Edge layer も WebApi にアップデートします。
 実際やってみたら、普通の Controller から ApiController に直して、IHttpResult か HttpResponseMessage に変更して、全ての Unit Test を通して、完了かと思いました。テストしたら、なぜか幾つかの Acceptance Test が通らなくなった。。。
 詳しく調べてみたら、主に下記の二点になります:
1 まず、戻り値について、以前 MVC4 の場合、Json(null) は空の Response body になりますが、WebApi の場合、"null" になります。これで、正しく deserialize できない Json ライブラリがあって、例えば、iOS では、null は間違った Json というエラーになります。ただ、Newton Json では、null 値になります。Android も問題なく、実際の null になります。結局 iOS だけかと思って。。。それで、Controller で null の場合、Ok() を返すように 修正しました。
2 もう一つの問題点は MVC4 では ModelDataBinder を使っていますが、Request headers, query string, body を探して、引数の Object を作成します。WebApi になると、primitive タイプ(int, double など)の場合、query string から、ModelDataBinder を使って、バインドするようになっています。複雑なオブジェクトの場合、Formatter を使って、Body から作ろうと。もし見つからない場合、もうあきらめるので、null になります。このデフォルトを変える場合、[FromUri], [FromBody] という属性を使って、WebApi に”このオブジェクト” はバインド FromUri ですと明白に指定する必要があります。

 他には、StartUp.cs を WebApi ものに変えたりして、簡単にできます。将来的にはやはり Api なら WebApi を使ったほうがいろいろ簡単な機能がありますので、使いやすいです。
 それでは。また。

2015年9月12日土曜日

C# asyn と await の使い方

 先週、やっとアプリを App Store にサブミットしました。ついでに、バックエンドの Web Api も Refactoring して、もっと速くなりました。その改善の一つとしては、HttpClient を使って、他の Endpoint からデータを取得する処理を全て async にしました。たとえば、三つの Http Call をするところ、await Task.WhenAll(<TaskList>) を使って、Concurrency になりました。三つ Call を並べたら、500 ms * 3 の処理を、500ms ちょっとでできます。
 ただ、一つだけ、最初は Task.Run() を使って、そのタスクを await しようとのコードを発見しました。それは間違いです。なぜなら、Task.Run は Thread pool から一つのスレッドを申請して、そのタスクを実行しようとします。本来、現在のスレッドを await すると、もっと別のリクエスト処理できるのに、逆にもう一つのスレッドを使ったので、async の意味がなくなります。タスクを await すると、IO の処理は実行している間、CPU Heavey の処理が実行できますし、今のスレッドを一時的に手放して、他のリクエストも処理できます。遅い IO 処理が終わったら、また元の Call Context から処理を Resume して、本来のタスクを完成します。
 一つの Best Practice としては、async を使うと、Top-Down で全てを async にしたほうがいいです。そうしないと、デッドロックが発生するかもしれない。参考として下記のブログが詳しく説明されています。
 async を block しないで

 また、ASP.NET で await void を関数をできるだけ使わないでください。こちらは実際問題が起こされて、一つの AWS Box が応答しなくなりました。原因はまだ調査していますが、await void は結構危険です。
 それでは。

2015年8月22日土曜日

Event Handler を DOM 要素に Bind する時のテクニック

 先週、ついリリースしました。今はアプリの App Store と Play Store の承認を待っています。たぶん大丈夫でしょう。最後のバグは jQuery 関係の Event Handler の Bind です。ある <a> tag のクリックに ScrollTo の jQuery Animation を呼びたかったが、アニメーションが実行されなくて、普通に飛んで行きました。
 詳細を調べてみたら、本来すでに Click に Handler を Bind して、 ScrollTo を呼び出しましたけど、チームの新人さんがそれが知らなくて、別の関数で実現しました。しかも stop(true, true) で前のアニメーションを全てキャンセルして、自分のアニメーションを実行していました。考え方としては問題がありません。ただ、stop() の第二の引数 jumpEnd です。true を渡すと、前のアニーメーションの最後までいきなり実行します。これがバグのルートです。ただ、stop(true) を呼ぶと、普通に正しく実行できました。
 最初は大騒ぎでしたが、問題はどこにも存在するイベントの Bind です。もし、全ての Bind を各ページに譲って、固定の箇所にしたら、たぶん新人さんでも気づくでしょう。たとえば、jQuery.ready() の中、ページの js ファイルに定義するとか。もし複数のページが同じコードが使うなら、main.js の固定場所に 置くとか。
 もう一つはアニメーションの使い方です。むやみに全てのアニメーションをキャンセルするのがどうかと思います。気軽に全てを止めったり、キャンセルしたりすると、思わぬバグに繋がります。
 幸い新人さんがすぐ私に聞いたので、コードはよく知ってるので、すぐ直しました。今後、どこで何をするかを一応ドキュメントにも残したいと思います。
 後、Back End のデータベース Oracle が AWS で他のチームと衝突したので、SQL Server に乗り換えました。後日また詳細を。
 それでは。

2015年8月3日月曜日

セキュリティ:クッキー

 つい先週、最後のセキュリテイチェック、パフォーマンステスト、Non-Functional テストが終わって、開発した Web API が live になりました。そのチェックの中に、クッキーの設定について、指摘がありました。ASP.NET を使ってるので、web.config に下記の設定追加しろうと。
   <system.web>
        <httpcookies httpOnlyCookies="true" requireSSL="true" />
   </system.web>

 今回の Web API では、セッションは OAuth を使っていますし、各 Endpoint は完全に Stateless で、クッキーとか使っていません。ただ、念のため、上記の追加しました。
 クッキー値の設定では、四つのフラグが あって、この中の二つは httponly と secure です。
 httponly を設定すると、JavaScript からそのクッキーの値が見えなくなります。ただ、クッキーは browser の 各 request には存在します。こうすることで、 document.cookie が .ASPXAUTH などのセッション Id が見えなくなるので、ajax でのセッションハイジャックはある程度防げます。
サーバーから Set-cookie の値が以下になります。
  Set-cookie: sessionId=abcdef; path=/; HttpOnly

 もう一つの requireSSL フラグは secure フラグをクッキー値に設定します。つまり、scheme は Https の場合のみ、クッキーをサーバー側に送信します。http でサイトを見る場合、または http で image などを要求する場合では、そのクッキーが見えません。
サーバーから response での Set-cookie は以下になります。
  Set-cookie: sessionId=abcdef; path=/; Secure

 こうすることで、ある程度クッキーが保護されます。別にクッキーが使わなくても、フラグを true に設定したほうがいいでしょう。
 覚えておこう。

2015年7月30日木曜日

React.js と AngularJS、どっちがいい?

 追加:下記は React.js 実際使う前の書き込みです。こちらも:
 React.js Vs AngularJS、どっちがいい その2
 React.js Vs AngularJS、どっちがいい その3 - React.js 速い!
 
 最近、隣のチームのプロジェクトでは AngularJS がヘビーだから、 React.js にしたと聞きました。最初、そのチームは AngularJS を使って、Demo を作りました。モバイルでテストすると、何かウェブサイトがすこし応答が遅いと思ったそうです。でも、それは AngularJS の問題ではないと思います。実際向こうのデモサイトを見てみたら、$timeout() がいっぱいあったりして、Directive もいっぱい作って、本来計算が終わったら、$apply を使うべきところを全部 $timeout を使ったりしていました。Angular の使い方としては間違ってると思います。Dirty Check はただ Model 変化をチェックする方法の一つです。Getter Setter の中にいろいろ判断するより、Dirty Check は理解しやすいし、重い処理は Framework に譲れたと思われています。
 まぁ、そのチームが React.js に乗り換えったら、Flux を使って、プログラム全体の構造は3年前 Backbone.js を使った時とほぼ同じになりました。実際デモサイトと比べると、それほど速いと思われてないし、勉強とか、Cross Browser の対応とか、またいろいろ苦労したそうです。最初デモサイトがモバイルでは重いと思われたことは 300ms Click との関係もなくはないと思います。
 しかも、React.js を使ったら、プログラム全体がわかりづらくなりました。Flux の Dispatcher を理解しない限り、どこで、何が更新されたかさっぱりわかりません。。。
 逆に AngularJS だったら、Controller, Service とかすぐ見つかるし、Back end の開発者もある程度見ればわかります。
 多分、区別はそこだと思います。React.js は Framework というより、ライブラリだと思います。つまり、アプリとみなすには、Flux などイベント Dispatcher、Model などをまた作らなければなりません。それを考えてみると、Polymer のほうが使い易いと思いますし、速度的には React.js の Virtual DOM より、それほど遅くないと思います、どうせメモリ上の比べだから、Dirty Check でも。
 将来 AngularJS 2.0 をかなり期待できると思います。Polymer とのシームレスとか、遅延ロードとか、Framework としてはかなりいいフィーチャーになります。
 
 まぁ、まだ React.js を詳しくみてないから、こう思ってますが、実際 React.js を View にして、AngularJS の Framework に組み込んだら、面白いかもしれません。
 今のプロジェクト一段落したら、また React.js を使ってみて、AngularJS と比べたいと思います。
 それでは。今現在の考えで。

2015年7月5日日曜日

Youtube ビデオを responsive にする方法

 先週、モバイルの WebView を使って、文章を表示する機能をアプリに追加されました。エディターから一つの要求は youtube のビデオを表示したいです。基本的に文章は Responsive をしているので、コンテンツは問題なく各種のモバイルスクリーンサイズが適応できますが、youtube ビデオは iframe の中にあるし、youtube の JavaScript ライブラリで作成されますので、responsive にするには with と height を 16:9 で固定する必要があります。ただ、iframe のサイズを変更するには JavaScript 以外だったら、すこし難しいです。特に、JavaScript を web page に使いたくない時があります。
 調べて見たら、css- trick からcss だけで youtube ビデオを responsive にする方法がありました。まず、ifarme にラッパーに置きます。html は以下の通り:
<div class="video-wrapper">
    <iframe width="480" height="270" src="http://www.youtube.com/embed/{youtube-video-id}?rel=0&hd=1" frameborder="0" allowfullscreen></iframe>
</div>

そのあと、css:
.video-wrapper {
position: relative;
padding-bottom: 56.25%;   /* 16:9 */
padding-top: 25px;
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

ここのトリックは padding-bottom です。パーセンテージにすると、width の長さになります。ここ 56.25% を設定すると、width とのアスペクト比は 16:9 になります。
 次、iframe を 100%, 100%, position を absolute に設定したら、親要素の中にフル表示されます。
 参考にしたページは

 css でいろいろできるなと。例えば、これ:

 それでは。

2015年6月28日日曜日

RESTful API データが見つからない場合の処理

 今 RESTful API をベースに iOS や Android のアプリにデータを提供するシステムを作っています。基本的になんでも json を返します。それで、HTTP メッソードを使ったり、 HTTP Response コードを使って、フロントエンドとやりとりをしています。
 HTTP メッソードの方は特に決まってるので、Read (Get), Create (Post), Update (Put または Patch), Delete (Delete)特に問題が起きてませんでした。まぁ、たまに Read を Post メッソードを使う API もありますけど。(GET には HTTP body がルールとして使わないので、複雑なオブジェクトをバックエンドに送る時、例えば、複数検索条件とか、Post も使ったりします。)
 戻り値は HTTP Response コードなので、200 OK, 201 Created, 202 Accepted とかは理解しやすいです:Get (200 OK), Post (201 Created), Put/Patch (200 OK), Delete (200 OK) 一見ですぐわかりますので、唯一考えるべきコードは 404 Not Found ですね。
 私見ですが、データが見つかってない場合、404 ではなくで、空の データ body を返すべきです。なぜなら、404 には url が存在しない場合もサーバーから返すので、意味が紛れ易いです。
 一般的に JSON を扱うライブラリでは空の配列や []、オブジェクト {} など空のデータに deserialize しますが、空の body の場合、null に deserialize します。それで、Front End が null かどうかチェックすればいいのです。
 404 が返す場合、これは HTTP Request がエラーになったと同じ意味なので、違うルートになります。だからコードには
   if (response.StatusCode == 404) {...}
みたいなコードがあっちこっち出てくるかもしれません。そうすると、全体的にエラーの扱いが難しくなります。
 データはデータなので、見つからない場合は、200 OK, null body を返したら Front end もすぐわかります。
 もう一つは Java, Objective-C, C# などは全て Strongly typed 言語なので、JSON を deserialize する場合、一般的に一つの Class を定義しますが、データの角度から見ると、処理に合わせて、たまに Dictionary<string, object> にしたほうがやりやすい場合もあります。
 例えば、JSON オブジェクトの中に、どのプロパティの値が null かをチェックする場合、Reflection を使うより、直接 Key-Value pair にしたらい、Iteration メッソードを使えば、速いし、その後の処理も楽になるはずです。
 それでは。ここまで。

2015年6月14日日曜日

祝 Polymer が 1.0 になりました

 先日、つい Polymer JS が Product Ready (1.0) になりました。
 https://www.polymer-project.org/1.0/

 これは Web の Future と言って、なかり使いやすいです。
 また、将来 AngularJS 2.0 ではシムレスに Polymer の要素を Directive と使えることができます。

 PS: React.js はどう見ても、FaceBook など表示に重点をおいたサイトでは使いやすいかもしれませんが、Interactive の重いアプリではやはり AngularJS のほうがいいと思います。
 後日また。

なぜ RESTful API になったのか

 おととい、チームの iOS Dev といろいろディスカッションしました。彼はまだ古い API のイメージ持っておらず、なんでもサーバー側でやると考えているようです。それで、現在の API は iOS だけではなく、Android, Web などいろんなチャンネルで共通で使う物だと、RESTful API だから、リソースを操作すると考えようといろいろ話しましたが、まだまだ受け入れてなかったそうです。
 以前、3 年前ぐらいまで、iOS デバイスなど、JavaScript の性能がボットルネックだった時代では、サーバー側で計算したり、ソートするなどをやらなければならなかった。当時の Front End はそれほど遅くなかったと言っても、パフォーマンスにいろいろ真剣に取り組まないと、すぐ遅いと感じてしまいました。それで、自分たちのラブラリを作ったり、速く見せるため、ユーザーの動作を予測して、先にデータをロードするなど、工夫していました。
 今 RESTful API になってから、抽象したデータなどをリソースと考えて、HTTP Method をマップして、CRUD -> Get, Post, Put (Patch), Delete を使って、Front end から直接操作できるようなイマージにしないといけないと思います。だから、API はデータを提供するだけ、データの操作はデバイスか Web Site で処理します。
 前では URI や Controller の名前は RegisterDevice など、動詞+名詞でしたが、RESTful API になると/devices と名詞のみなりました。それで、HTTP Get で全部のデバイスを取得したり、 HTTP Post でデバイスを作ったりします。
 GET /devices?pageNo=0&pageSize=20  -> 全部のデバイスの配列を取得
 GET /devices/{deviceId} -> 一つのデバイスを取得
 POST /devices -> デバイスを作る。データは HTTP Request Body から
 PATCH /devices/{deviceId} -> デバイスを更新
 Delete /devices/{deviceId} -> デバイスを削除

 また戻りますが、Front End は一回要求するデータはそれほど多くないので、ソートも時間のかかる処理ではなくなりました。Http Request の時間はまだ考えなければなりませんが。
 結論としては、もう新しい時代ですので、表示ロジックを Front End であるべきです。
 それでは。

2015年5月31日日曜日

Task.Run と Autofac データベース Connection 問題から、サーバー側マルチスレッドの検討

 今開発しているシステムは HTTP を使って、RESTful API です。Front end は iOS から、Android、WebSite 全部サポートしています。デバイスの 3G 回線でも、できるだけ速くロードするために、いろいろ工夫しました。例えば、一つ目のレスポンスに各リソースをリクエストする URL を入れて、実際の作成は後回しして、マルチスレッドを使います。さらに、Task.Run を使って、できるだけ時間のかかる処理を別のスレッドで行うようにします。一方、Oracle DB Connection などは Autofac を使って、 DI の .InstancePerRequest() で各スレッドに配っています。そうすると、Task.Run は Thread Pool に新しいスレッドを申請してので、そのスレッドでは前の Request のスレッドのリソースが使えなくなりました。。。"Invalid operation on a closed object" みたいなエラーが発生したりしています。毎回ではないですが、かなりの確率で発生しています。
 解決の方法としては、Task.Run を使ってるスレッドの中に、自分で Autofac の LifetimeScope コントロールすることです。 まず、LifetimeScope の Provider を作って、RequestLifetimeScopeTag を ILifetimeScope の作成関数に設定することで、この ILifetimeScope は Request Scope として指定できます。ただ、自分で ILifetimeScope を作ったから、Scope の Dispose() 関数を自分で呼び出す必要になります。後日まだどうするかのコードを貼り付けます。
 ここでまず話したいことは Task.Run を使う場合、スレッドの切り替え処理もありますので、一般的に 50 ms 以下のタスクでは別スレッドを使う必要がないのです。
 Task.Run は Back End でファイルを書く場合や、HttpClient を使って、他のスステムに Http Request を発行する場合使ったほうがいいです。一般的な DB アクセスには速度がかなり早いので、20ms ぐらいと言われているので、必要がないと思われています。
 もし Loop を使って、DB 更新を行う場合や、複数のテーブルを更新するが更新結果は Front end に返すする必要がない場合、できるだけ小回りにして、複数回で更新したほうがいいです。この処理は Task.Run を使うより、Hangfire などの Background タスク Runner を使ったほうがいいです。Hangfire は DB を使っているので、Retry 処理もあるし、Task.Run より安全です。
 Front end から見ると、Http API を呼ぶとき、レスポンスが戻ってきたら、 Callback 関数が呼ばれるので、一回の Http Request より、複数の Request を発行して、各 Callback 関数を呼び出して、UI をアップデートしたほうが速いです。Http Request 自体がマルチスレッドでサーバー側で処理するので、それを最大限に使わないと。

 それでは。

2015年5月16日土曜日

iOS ユニバーサルデザイン実践:イメージのセンター揃い

 この Sprint では、チームの iOS Dev が休暇で一ヶ月ほど離れることになりました。あまり Native サイドのコードを触りたくないですが、急いで実現したい機能があったので、一週間ほど Objective-C を使って、 開発をしました。
 まだ iOS の開発では Nib をベースにしていますが、xib フィアルの代わりに StoryBoard が使われるようになりました。さらに、違うサイズのデバイスを対応するために、ユニバーサルデザインという概念が導入されました。これは前と違って、 絶対位置を指定するより、Constraint を使って、相対位置とサイズを指定することで、大きい iPhone 6 plus から、細長い iPhone 5 まで、全てのスクリーンサイズを対応できる layout nib になります。
 さらに、Segue という概念が導入されて、前のように ViewController を push するコードより、もっと具体化になるものです。Ctrl を押しながら、ドラッグして、次画面はどこに遷移するかを指定します。これも面白いです。
 今回の機能は幾つかのイメージをスクリーンの真ん中に表示することです。前なら、イメージビューをプログラムで作成して、addSubView を読んで、画面に追加します。そのあと、Frame を取得して、計算後、位置を指定します。少しは面倒くさいデスけど。
 ただ、ユニバーサルデザインでは、これは変なコードになるので、どうするかを少し調べたら、一番いい方法が見つかりました。
 具体的に、parent view を作って、centre align の Constraint を指定します。同時にこの Constraint をoutlet で view に追加します。Constraint の Constant などのパラメーターが取得できるようになります。
 次、イメージを parent に追加したら、parent view の width を取得して、先ほどの centre constraint に設定します。これで、どうなスクリーンサイズでも、parent view がセンターになります。
 
 Constraint は iOS が各ビューの位置や、サイズを決めるために使ったものなので、さらに面白い使い方がありますね。さらに、こちらの値もアニメーションで使えるので、前のように origin.y を使ったりすることなくても、 view を動かしたりすることもできます。
 それでは。

2015年4月29日水曜日

javascript で Native iOS app 開発

 昨日、これを発見しました。
 facebook react-native

 少し見てみましたが、基本的に javascript で、JSX を使って、native ios app を作るというものです。PhoneGap と違って、基本的に javascript コードが objective-c コードに、JSX は NIB ファイルになるような感じです。
 
 react JS ライブラリと違って、これはモバイル向けで、将来は Android, Windows Phone もサポートするそうです。
 すでに App Store に https://itunes.apple.com/app/id964397083 こういうアプリが公開されたそうです。

 まぁ、そんなにパワフルなものではないような気がしてますが、いい試しだと思います。ただ、使う気がない。。。

 最近 Objective-C を使ってるので、swift に比べると、まぁ、幾つか Syntax Sugar 以外、Objective-C のほうがマシだと思ってますが。
 
 再来、facebook から何か出てくるかな。。。

 それでは。

2015年4月19日日曜日

AngularJS Directive の使い方

 おととい別チームの Front End Dev に Directive のオーダーについて聞かれました。そのプロジェクトでは ng-model の隣に、入力値のチェックやフォーマットを全て個々の Directive で行われています。いっぱい Directive が書かれていて、コードを読むにはちょっと大変です。。。それで、問題となってたところは二つ Directive の中に、onblur を使って、入力値をチェックしたり、値を変えたりしてました。ただ、onblur のコールオーダーによりページには変な動作になりました。それで、onblur の handler の呼び順番変えられるかと聞かれました。
 少し、彼らの Directives を見てみると、あまりいいアプローチと思ってませんでした。なぜなら、priority も設定してないし、ng-model の中に formatter と parser キューがありますので、本らなら、それを使って、すぐできる機能なのに、全て onblur の中に書いてしました。
 まぁ、一番大事なのは問題を解決するので、まず、directive に priority という属性がありますので、それを使って、direcitive の link function を実行するオーダーが変更できます。具体的に言うと、AngularJS はまず一つの element に attach した全ての directive を array に入れて、そのあと、priority を使って、Sort してから、link を呼び出してます。それで、directive の onblur を呼ぶ順番は変えられます。
 まぁ、もう一つの方法は $timeout を使って、次の digest circle に実行することです。ただ、これは間違いだと思っています。$timeout はあまりにも使いすぎてる感じがあります。何か動かなかったら、すぐ $timeout を呼ぶとか。。。
 注意すべきところは $timeout では、$rootscope.apply() が呼ばれているので、全てのあたりが一回 digest されます。もし複数の $timeout が呼ばれるなら、ページはずっとリフレッシュされます。。。これは AngularJS が重いと言われた原因の一つだと思います。

 今回なら、ng-model すでに formatter と parser があるので、それを使うべきだと思います。それに、一つの機能を一つの directive に入れるのはあまり良くないです。いっぱい directive になると、さらにその中に jquery などを使って、DOM 操作すると、オーダーが難しくなります。もし、単独の directive を使うなら、カテゴリにより機能をまとめるべきです。例えば、入力値のフォーマットをチェックするなら、全てのチェックの一つの directive にまとめた方がいいです。そうすると、$validate でエラーメッセージを設定には簡単になります。表示の順番も操作しやすくなります。
 
 本来なら、Framework は裏でいっぱいやっているので、その処理を知るべきだと思います。例えば、directive の compile、link function はどのように呼ばれているかとか、angular の bootstrap はどのように実行しているかとか。それを知らないと、パフォーマンスのいいアプリは作れるには難しいです。
 
 それでは。

2015年3月29日日曜日

モバイル App 起動とApp Store, Play Store に Redirect する Landing Page

 先週、メールを使って、情報をシェアしたりする機能がうちのアプリに追加されました。メールには HTML リンクがあって、その後ろに token があります。具体的に言うと、もしユーザーが App をすでにインストールしたら、直接アプリを起動します。もしユーザーがアプリをインストールしてなかったら、App Store か Play Store に転送します。
 これを実現するにはメール中のリンクをクリックするとき、 Landing Page をモバイルのブラウザーに開いて、JavaScript で userAgent をチェックして、まず App を立ち上がることを試して、もし起動しなかったら、iOS なら、App Store, Andorid なら Play Sotre を開きます。
 コード:
  isIos = /iP(one|ad|od)/i.test(navigator.userAgent);
  isAndroid = /Android/i.test(navigator.userAgent);
 
  redirectUrl = {
      iOS : {
         app: 'appscheme://path/parameter',
         store: 'https://itunes.com/abc123456'
      },
      android : {
         app: 'appscheme://path/parameter',
         store: 'https://play.google.com/abc124?token=123abc'
      }
  };

  if(isIos || isAndroid) {
      redirect = isIos : redirectUrl.iOS : redirect.android;
      launchTime = +new Date();

      window.location.href = redirect.app;  // You can add any query string here
      setTimeout(function() {
        if((+new Date() - launchTime) < 2000) {
          window.location.href = redirect.store;
        }
      }, 100);
  }

 説明すると、まず iOS か Android かを userAgent をチェックして、そのあと、アプリを起動するのを試します。こちらはアプリ特有の scheme を使って、url を転送するのを試します。もしアプリが起動したら、ブラウザーからアプリに切り替えるので、次の setTimeout の関数は 2 秒ご実行されるはずです。そうすると、store url への転送が実行されないはずです。
 もしアプリが起動されてない場合、 100 msを待ってから、store url への転送が実行されます。
 今後、たぶん widows phone バージョンも追加されるだろう。ただ、原理は同じです。
 それでは。

モバイル 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 を実現するには、この遅延をなくすことは大事です。
 それでは。

2015年3月11日水曜日

ASP.NET Lib Practice

 最近、つい完全に Back End 開発者になりました。毎日 C# コードだけを書いて、なんだか JavaScript が使い易いなと思いました。同じ機能だったら、JavaScript のほうが少ない行数でできるはずです。将来は Node.js かな?でも、Strongly Typed 言語はやはり錯誤が少なくなります。ちょっと面倒くさいですけど。
 最近面白そうな ASP.NET のライブラリをリストしよう(まぁ、幾つかの機能は Java なら Spring だけで全部できてしまいますけど。。。):

 まず、Hangfire です。これは ASP.NET MVC と並行して、Background でタスクを実行するライブラリです。例えば、ユーザーが登録したら、email を出すと。現在一般的には1日終わる時点で、バッチタスクで新規登録したユーザーにメールを出します。Hangfire には fire-forget Job Queue がありますので、しかも別スレッドで実行してます。Controller 関数の最後に BackgroudJob.Enqueue を実行すれば、関数がすぐ返しますが、Email が別 job で送られます。しかも、遅延とか循環 job も作れますので、使い易いです。まぁ、個人的には Redis を使う意味があまりないと思うので、フリーバーションで十分だと思います。

 次、Autofac です。DI Container なら、Ninject とか Unity とかもありますが、Autofac の機能とSyntax は使い易いと思います。ILifeTimeScope も inject できますので、Life time scope を使いたいとき、または使ったほうがいい時、すぐ使えるので。例えば、DBContext は Thread Safe ではないため、一つのスレッドに一つ定義したほうがいいでしょう。MVC になると、一つの Request に合わせて、一つの DBContext を定義するなら、.AsPerRequest() 関数が提供されてますので、すぐできてしまいます。

 あと、Coypu です。これは Protractor や、Capybara みたいに、Selenium Server を使って、自動テストを C# コードで実現するライブラリです。個人的には AngularJS の Protractor のほうが AngularJS にあってるので、でも C# でテストケースをかけるなら、結構な人数の Backend 開発者も End 2 End テストができます。

 他に CacheCow 自動的に ETag を追加して、in memery cache のライブラリです。CacheCow-Server と HttpClient 対象の CacheCow-Client があります。

 Unit test 用の FluentAssertions, Object 属性をマップする Auto Mapper, OR Map の Dapper.NET、Validation 用の FluentValidation, Moq 以外 NSubstitute なども使い易いです。次のプロジェクトにいろいろ使ってみよう。

 でも、こちらのライブラリは、SignalR と Socket.io 比べるように、やっぱり JavaScript のほうが面白いな〜

 それでは。

2015年2月28日土曜日

URL absolute path and relative path

 昨日 AngularJS の $http を使って、AJAX でデータをロードするウェブページをデプロイしたら、ページロードが失敗して、web inspector で見てみたら、xxxx/xxxx url がアクセスできないエラーでした。
 実際見てみたら、別に $location などは使ってないし、なんでロードが失敗しただろうと思って、少し調べてみました。それで、$http を呼ぶとき、"/xxxxx" ような URL を使っていました。これは root の後ろにつく absolute path になるので、ウェブページはサーバーの一フォルダに置いたので、当然アクセスできませんね。
 <a> タグの href 属性と同じように、URL を使うところもし "/xxxxx" で始まると、同じドメインのリソースになります。例えば、ウェブページの url は http://www.abc.com 場合、<a href="/def"></a> をクリックすると http://www.abc.com/def になります。これは絶対パスと言います。
 もし <a href="def"></a> の場合、もしウェブページは前と同じなら http://www.abc.com/def になりますが、もしウェブページが http://www.abc.com/pages にある場合、a タグが http://www.abc.com/pages/def の方に飛びます。これは相対パスです。
 基本的には前に "/" があるかどうかで全て分けます。相対バスの場合、単純に "def" を指定するか、"../def" のようにカレントウェブページをベースに、親フォルダの def に指すような書き方があります。
 もし static ファイルとウェブページが同じドメインにある場合、良く script タグの src を ../../Scripts/js/jQuery.js を指定したりしました。(今はロードスピードを早くするために、すべての static ファイル - images, css, js - を別ドメインに置いてます。)
 まぁ、個人的にはあまり絶対パスを使わないほうがいいと思っています。それを使うと、どこに行くかちょっとややこしくなります。もし使いたい場合、全部の http url を書いた方がいいと思います。場合にもよりますが。

 ちなみに、http を書かなくて、 //www.abc.com/def の場合、アクセスするウェブページの URL から protocol をとって、アクセスします。例えば、ウェブページが https を使ってる場合、https://www.abc.com/def になります。

 今 RESTful API を書いてますので、タグの src とか href とかとあまり関係ないが、パスが http cache とも関係があって、気をつけないといけないですね。今は CacheCow を使って、ETag を自動的に生成するライブラリを使ってますけど。後日また詳細を追加します。C# の HttpClient とか。

 今日はここまで。それでは。

2015年2月22日日曜日

C# ASP.NET Web RESTful API と Front End

 最近、仕事が Back End の方にシフトしました。以前も C# ASP.NET を使ってましたが、あまり印象が良くなかった。ただ、今回 MVC4 を使ってて、なんかコンセプトなどは Ruby on Rails に似てるなと思いました。でもやはり JavaScript の方が使い易いです。
 今作ってるのは UI いわゆる View のない API のみになります。すべてのリソースを操作できる HTTP Method を使って、RESTful です。ASP.NET Web API を使うと、結構簡単にできます。しかも Autofac を使って DI も実現できるし、あまり他の言語のフレームワークと変わらないなと思いました。
 そうすると Front End はもう最初からデータをロードするではなくて、スタティックのリソースだけロードすることになります。ページが早くロードできる利点もあるし、そのあと API を呼び出す事で、どのように表示するかも簡単に変更できます。
 さらに、Task<IHttpActionResult> の戻り値のようにマルチスレッドのコントローラーもサポートしているので、Node.js みたいに他のリソースを要求して、処理が終わったら、HttpResponseMessage などを返すようないわゆる Event Driven のスタイルもできます。このスレッドは ApplicationPool ではなく、他の pool を使うので、いつでも Request が受け付けるようになります。
 あと、NSubstitute を使ったり、Moq を使うことで、Unit Test も簡単にかけるから、全体的にいい感じです。
 
 今回もプロジェクト全体が Mobile First を利用するので、まず iOS と Android Smartphone を対象に、リリースする予定です。今までは、ほとんど Hybrid の App を作ってきたので、今回もそれになりそうですね。
 
 それでは。

2015年2月10日火曜日

AngularJS パフォーマンスは良くない?ー>いいえ、使い方次第です。

 アップデート 2016/05/01:AngularJS 1.0 に比べて、React.js のほうが良いです。AngularJS の bi-direction binding、ng-repeat などは使い易いですが、DOM 操作が多くて、重いです。React.js も同じ機能が簡単に作れます。さらに、AngularJS 1.0 の Learning Curve が高いから、習うにはなかなか時間がかかります。React.js を使うと、どんどん Component が作れて、ますます開発効率が上がります。

 追加 2016/03/07:最近、React.js を使うたびに、AngularJS は難しいなと感じ始めています。1.0 では概念が多くてなかなか使いにくいですね。React.js の場合、概念も簡単だし、Flux を使うと、アプリの構造はかなり簡単になります。また速いです。まぁ、速くするためには、shouldComponentUpdate 関数を細かく実装すればいいので、はっきりしています。今後続けて React.js を使おうと思います。新規プロジェクトの場合、AngularJS 2.0 を待ったほうがいいです。でも、古いバージョンのブラウザをサポートするためには、React.js のうほうがよさそうです。時間があれば、また http://aurelia.io/ を見てみようかと。Polymer はどうやら、遅いようなきがしています。。。後日、ちゃんと勉強してみよう。

 最近、隣のグループは react.js に転向したので、再び AngularJS のパフォーマンス問題が提起されました。実際はどうですかね。。。
 まぁ、個人的な感じでは、JavaScript 根本的にパフォーマンスが良くないです。AngularJS は良く重いと言われてます。特に Dirty Check の実行サイクルが考えば考えるほど重いと思われています。でも、どんなフレームワークでも、react.js、ember.js でも、そういう長いループが存在しています。だから、Dirty Check はそんなに大きいな問題でもないと思います。
 問題は利用者側にあると思います。なぜなら、たぶん結構な数の開発者は $timeout や, $http の中に $rootscope.$apply 関数が呼ばれてると知らないです。それで、無意味に $timeout を呼んだり、自分でその中に $apply を使ったりしています。そうすると、AngularJS は2回 Dirty Check をやるので、重いですね。
 つまり、フレームワークとして、AngularJS はあまり複雑で、なかなか全部理解するには時間がかかります。そのあと、チューニングとかもしないから、問題を発見して、解決するプロセスが欠けてます。
 じゃ、どうしたら AngularJS のパフォーマンスが向上できますかね?
 まず、$apply 関数を理解しましょう。$apply 関数は $digest 関数を読んで、もしエラーとか、Exception が発生したら、ちゃんとエラースタックをリストできます。(中に try-catch があるので)。$digest  は登録した expression を実行して、過去の値と現在の値を比較して、変更があったら、変更の Handler 関数を呼びます。Handler 関数の中にもし何か値変更があったら、また $digest が実行されます、変更がないまで、実行し続けます。それで、$digest が10回まで繰り返し呼ばれます。10回以上の場合、Exception が Throw されます。
 それで、もし登録した expression の数が最小限に抑えるなら、そのサイクルが短くなります。AngularJS 1.3 から {{::express}} が導入されました。もし expression が最初の一回のみ値を設定する必要があるなら、:: で一回のみ binding されます。これも bind-once という関数があります。また bindonce という別のライブラリもあります。
 あと、すべての HTML 要素を ng-app 範囲にする必要がないので、例えば ng-non-bindable を使ったりして、directive の parse 範囲を小さくすることができます。以前も書いたように、jQuery UI を使うと、かなりの量の HTML 要素が作られます。それを parse するあまり必要ないし、"IE FIX" コメントも追加されますので、たまに Widget を壊します。だから、必要のない部分はもう non-bind して、apply directive 過程を止めます。
 次、1ページはすべて AngularJS の ng-app 範囲にすると、かなりの expression 量が増えますので、controller を親子にしないで、独立のスコープなら、もうそのスコープの $digest 関数を呼ぶとか、Dirty Check の量を減らせます。
 
 まぁ、よほど大きい web app じゃない限り、AngularJS のパフォーマンスは悪いと言えないと思います。すべて使い方次第ですね。
 どんなフレームワークを使うと、必ず overhead が発生しますので、良くデザインして、必要な部分と必要ない部分をちゃんと分けて、パフォーマンスは良くなります。

 #余談ですが、jQuery のパフォーマンスはかなり悪いです。通常の Vanilla JS を使うと、同じ関数が jsperf.com でテストすると、なん百倍の差が出ます。なぜなら、ライブラリだから、エラーチェックや、browser の違いを綺麗にカバしたいからです。以前 iOS の WebView も jQuery を使うと重く感じましたので、jQuery Lite を作って、パフォーマンス向上できました。使い方次第ですね。

2015年1月25日日曜日

RESTful API のデザイン

 先日から、新しいプロジェクトが始まりました。いろいろデザインとか、ポソナーとか紹介されて、面白そうです。今回は旧システムの改造も、 UI の改善も、モバイルファーストでする予定です。
 バックエンドは完全に書き換えるではなくて、API を追加して、フロントエンドをサポートする形になります。だいぶのロジックはフロントエンドでやる予定です。それで、フロントエンドもっと自由にデータを操作できるのように、データも RESTful API に合うように、少し改造する予定です。
 RESTful API はリソースの C(reate)R(ead)U(pdate)D(elete) を Post, Get, Put, Delete HTTP Request にマップする技術で、今は結構使われています。MongoDB なども RESTful API を提供するモジュールもあったり、CouchDB は完全に内部サポートしています。Oracle の最近の Non-SQL DB もサポートしています。
 実際作るとき、例えば、ツイターのフォロー関係も一つのリソースと考えていいです。メンバーが 登録される後、他の人をフォローすると、このような関係を DB に入れる時、実体はないけどれ、 実存しています。
 今は AJAX を使って、HTTP の Method を指定することで、Delete など直接サーバーに送ることができます。もし、JavaScript が使えない場合、現在のフレームワークは Hidden フィールドを使って、そのままサーバーで、API にマップすることもできます。

 来週から、もう完全に API チームに配属されますので、しばらくは JavaScript 触れないが、最近出てくる新しいものがあまりないし、AngularJS 2.0 も開発中ですので、ちょっと待ちましょう。:)

それでは。