TL; DR: Web App のスピードにこだわりがあるなら、React.js を使おう。
追伸:新しいプロジェクトが始まる場合、AngularJS 1.0 を使わないで、できれば、AngularJS 2.0 を待ったほうがいいと思います。
その3で isomorphic (サーバー側レンダリング)を書こうと思いましたが、Reac.js のスピードに驚いたので、まず React.js について詳しくメモしておきたいです。
今作ってる Single Page Web App のサイズがだんだん大きくなって、ライブラリを除いて、Dev バージョンはつい 15K 行を超えました。一般的に Framework を使うと、アプリのサイズは小さくなります。ちなみに、Dev バージョンの AngularJS 1.3 は約 25K 行、React.js (Flux) は 18K 行ぐらいあります。
Web App の DOM Node は約 9500 で、メモリは 50M ぐらいを使っています。このサイズで、経験から、AngularJS はもう重くて、Dirty Check と DOM 更新は 400ms 超えることもあります。ユーザーは遅延が感じられるサイズになります。React.js の場合、サクサク動いてて、全然遅いと感じられません。
Framework 自身のコストもありますので、AngularJS や、Backbone.js などはすぐ DOM を更新する系は重く感じます。React.js の Virtual DOM はかなり快適に動いていることがわかります。
これは主に shouldComponentUpdate や React.addons.PureRenderMixin うまく使った結果だと思います。
React.js の場合、Component の state や props が更新されると、render 関数がもう一度呼び出して、Virtual DOM を更新します。さらに更新された Virtual DOM と前の Virtual DOM を比べて、変更された部分だけ DOM を更新します。さっと見ると、AngularJS 1.0 の Dirty Check とあまり変わらないじゃないかと。でも、実際はかなり違います。AngularJS 1.0 は DOM 更新を随時に行います。最初も DOM をスキャンーして、Directive を処理します。メモリなどはかなりのサイズで消耗していきます。React.js の場合、Virtual DOM の比較アルゴリズムはうまく仮想を立てて、shouldComponentUpdate もうまく利用して、本来なら O(n3) ですが、O(n) で実現できるようになりました。つまり、一回の比較で、もう変更点がわかるようになります。Dirty Check は 一回の Digest で2回実行されます。世の中間違って AngularJS を使っているアプリの中に、多分無数の $timeout を使ってるなと思って、Digest はずっと動いているかもしれません。デスクトップはいいとして、モバイルの場合、電池の消耗は速いと思われています。
でも Framework や Lib は使い方次第で、スピードがかなり異なりますので、今のチームでは、うまく PureRenderMixin を使って、state と props を比較して、Component の更新が必要ないなら、shouldComponentUpdate を false を返して、render 関数をスキップします。React.js の中にも false を見ると、その Tree を比較しないようになっています。下記のページもまとめています。
react.js advanced performance
Component には Lifecycle があります。なんでもかんでも setState() 関数を呼び出すと、react.js もさすがに重くなります。(前のチーム開発したApp はかなり重く感じられます。React.js でよかったなと思って、AngularJS の場合はもう重くて、重くて、使えないかもしれません。)
だから、componentDidUpdate や、componentWillReceiveProps 関数の呼び出すタイミングを測って、どのように Parent Component を更新するかとか、新しい props をもらったら、どのように state を変更するかとか細かく考えないと。できるだけ Component 不要な render 関数呼び出しを減らさないと。
それに、component は本当に state 必要かも考えましょう。必要ないなら、stateless の component を使いましょう。
AngularJS の機能が強いから、いろんな使い方がありますので、簡単にはアプリ全体の構造が壊されます。($timeout を使って、次の Digest を呼び出して、DOM を更新するという間違った使い方。。。)
React.js の場合、概念が簡単だし、機能はそんなに強くないから、逆にアプリ全体がきれいに見えます。
もし、アプリのスピードに要求がある場合、React.js を使った方がいいと思われます。
Code
2016年1月26日火曜日
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 使ってないので、来年早々やってみようと思っています。
では、また。
先月から、つい新しいプロジェクトが始まって、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 の再レンダリングします。
具体的に、どのように動くかは後日また詳しく。
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 を使ったほうがいろいろ簡単な機能がありますので、使いやすいです。
それでは。また。
実際やってみたら、普通の 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 は結構危険です。
それでは。
ただ、一つだけ、最初は 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 に乗り換えました。後日また詳細を。
それでは。
詳細を調べてみたら、本来すでに 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 に設定したほうがいいでしょう。
覚えておこう。
<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 に設定したほうがいいでしょう。
覚えておこう。
登録:
投稿 (Atom)