アップデート 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 を作って、パフォーマンス向上できました。使い方次第ですね。
Code
2015年2月10日火曜日
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 も開発中ですので、ちょっと待ちましょう。:)
それでは。
バックエンドは完全に書き換えるではなくて、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 も開発中ですので、ちょっと待ちましょう。:)
それでは。
2014年12月31日水曜日
擬似要素 (pseudo element) の取得
IE 8 から、擬似要素がサポートされて、現在すべてのブラウザーがサポートされるようになりました。:before や, :after を使えば、DOM Tree は時に綺麗になることがあります。例えば、アイコンをある要素の前に挿入した場合、通常 <i> 要素を入れるか、background-image を使って、padding を追加する方法がありますが、擬似要素の :before の content に url(xxxx) を入れると、background-image と同じ効果になります。そうすると、余計なことをしなくて、単純にそのアイコンを操作することができます。
昨日、サイトに :before 要素を javascript で取得して、操作しようとのケースがありました。擬似要素をどのように javascript で取得するかを調べてみました。メモしておきます。
window.getComputedStyle(element, ':before')
content attribute を取得する場合、上記で取得したスタイルの後ろに .content を追加すれば、取得できます。
また擬似要素の content に複数文字列を表示したい場合、単純に
el:before {
content: "Num" counter(item) "."
}
のようにリストすればいいです。
CSS にこのような擬似要素を使えば、いろんな面白い効果ができます。例えば:
CSS icons
また、今流行っている font graphic を使えば、例えば、
Font Awesome
このように、フォントを使えば、font-size を使えば、大きさも調整できるし、Retina の hi-res のスクリーンも難なく対応できます。SVG より、こっちのほうが使い易いと思います。
それでは。
昨日、サイトに :before 要素を javascript で取得して、操作しようとのケースがありました。擬似要素をどのように javascript で取得するかを調べてみました。メモしておきます。
window.getComputedStyle(element, ':before')
content attribute を取得する場合、上記で取得したスタイルの後ろに .content を追加すれば、取得できます。
また擬似要素の content に複数文字列を表示したい場合、単純に
el:before {
content: "Num" counter(item) "."
}
のようにリストすればいいです。
CSS にこのような擬似要素を使えば、いろんな面白い効果ができます。例えば:
CSS icons
また、今流行っている font graphic を使えば、例えば、
Font Awesome
このように、フォントを使えば、font-size を使えば、大きさも調整できるし、Retina の hi-res のスクリーンも難なく対応できます。SVG より、こっちのほうが使い易いと思います。
それでは。
2014年12月2日火曜日
スクリプットタグでのテンプレート問題
最近、IE 8 で Bad HTML の解釈が他のブラウザーと違ってて、プログラムが動かなくなったことが発見しました。
基本的に、あってはいけないことですが、<script></script> の中に、他の <script> tag が定義されて、W3C の標準に違反になりますが、ブラウザーは自分の解釈で実行できてますけど、どうやら、この場合、IE 8 だけ、</div> が追加されるそうです。。。
W3C の標準とブラウザーの実装は基本的に同じですので、</script> という close tag を探して、script の終了をわかるようになります。もし <script> の中に他の <script> tag を入れたら、このルールが破れますので、どのように実行するかはブラウザーに任せます。。。
これで、最新のブラウザー (IE9 ~) は問題なく、正確な HTML と同じように解釈しますけど、 IE8 は独自のルールに従います。。。
まぁ、IE 8 の使用率はもう 2% 以下だから、直さなくてもいいと思います。
それでは。
基本的に、あってはいけないことですが、<script></script> の中に、他の <script> tag が定義されて、W3C の標準に違反になりますが、ブラウザーは自分の解釈で実行できてますけど、どうやら、この場合、IE 8 だけ、</div> が追加されるそうです。。。
W3C の標準とブラウザーの実装は基本的に同じですので、</script> という close tag を探して、script の終了をわかるようになります。もし <script> の中に他の <script> tag を入れたら、このルールが破れますので、どのように実行するかはブラウザーに任せます。。。
これで、最新のブラウザー (IE9 ~) は問題なく、正確な HTML と同じように解釈しますけど、 IE8 は独自のルールに従います。。。
まぁ、IE 8 の使用率はもう 2% 以下だから、直さなくてもいいと思います。
それでは。
2014年11月20日木曜日
IE 11 userAgent 変更
今日、隣のチームが変なバグを遭遇しました。一般的には IE8 では動かないバグがよくありますが、今回は IE11 で editor が動かなくなりました。具体的に言うと、chrome などのブラウザーでは、rich text editor が自動的に生成されますが、IE 11 では普通の textarea になっていました。
ちょっと調べてみたら、なぜか、iframe が生成されるコードが実行しなくなりました。もう少し確認したら、IE 11 はサポートブラザー外になりました。
コードを追ってみると、userAgent を取得して、"MSIE" をチェックして、IE のバージョンを確認する処理がありました。IE 11 では MSIE という文字列がなくなったことが発見しました。
へ〜、本当に起こりました。。。こういうことは。
以前予想していましたが、実際起こるのですね。userAgent でブラウザーを判断することはよくないと以前から話してましたが、まだいろいろライブラリーがそれを使ってますね。。。
まぁ、ブラウザーの userAgent は相変わらずごちゃごちゃですけど。。。
今回は rv:11.0 からバージョンは取得できるので、それをコードに追加して、うまくいきました。。。ただ、他のスクリプットエラーが出て。。。
x-ua-compatible を EmulateIE9 に追加したら、実行できました。。。
なんでだろうね。。。
MS も IE 11 をおしているようです。面白いサイトです:
http://www.rethinkie.com/hello-again/#/intro
ちょっと調べてみたら、なぜか、iframe が生成されるコードが実行しなくなりました。もう少し確認したら、IE 11 はサポートブラザー外になりました。
コードを追ってみると、userAgent を取得して、"MSIE" をチェックして、IE のバージョンを確認する処理がありました。IE 11 では MSIE という文字列がなくなったことが発見しました。
へ〜、本当に起こりました。。。こういうことは。
以前予想していましたが、実際起こるのですね。userAgent でブラウザーを判断することはよくないと以前から話してましたが、まだいろいろライブラリーがそれを使ってますね。。。
まぁ、ブラウザーの userAgent は相変わらずごちゃごちゃですけど。。。
今回は rv:11.0 からバージョンは取得できるので、それをコードに追加して、うまくいきました。。。ただ、他のスクリプットエラーが出て。。。
x-ua-compatible を EmulateIE9 に追加したら、実行できました。。。
なんでだろうね。。。
MS も IE 11 をおしているようです。面白いサイトです:
http://www.rethinkie.com/hello-again/#/intro
2014年11月9日日曜日
protractor コマンドラインと補助ツール
基本的に、protractor の config js ファイルにあるものはそのままコマンドラインにパラメーターを書けば、上書きできます。常用のものは
--baseUrl="NEW URL" <- これでテスト対象の URL が変更できます。テストケースの中に browser.baseUrl から取得可能です。
--params.xxx.xxx=NEW VALUE <- もし、config js に pramas フィールドが追加されるなら、params の値を送れば、NEW VALUE が適用されます。
もし、一つだけのテストケースを実行したいなら、
--suites=SUITE NAME
--specs=TEST CASE FILE NAME
で、ターゲットスイート、テストケースファイルが実行できます。複数実行したい場合、 コマで区切れば、protractor がそのまま実行できます。
テスト結果のレポートは HTML バージョンは下記のライブラリをつかれば、簡単につくれます。スクリーンショット付きで。
package/protractor-html-screenshot-reporter
config js ファイルの onprepare 関数に Jasmine の reporter を設定すれば、自動でフォルダに HTML と画面キャプチャーが作成されます。
あと、selenium sever をサーバーのものを使いたいなら、
--seleniumAddress を使えば、どこかのサーバーアドレスに設定できます。localhost じゃなくて。
注意すべきところは、リモートサーバーを使いたいなら、タイムアウト時間をちょっと長めに設定したほうがいいです。
これも Jasmine のものと合わせて、config js ファイルに
allScriptsTimeout: 30000 <- WebDriver の script タイムアウト時間を 30 秒に設定
jasmineNodeOpts: {defaultTimeoutInterval: 30000} <- Jasmine timeout を 30秒に設定
あと、ページタイムアウト、これを browser.get(url, time) 第二の引数に設定するも可能です。
getPageTimeout:30000
どのブラウザーでテストするには、capabilities, multi-capabilities で設定できるので、注意は一つ。
IE の場合、IEDriver の問題で 64bit が超遅いです。IE 11も対応してないので、IE10 + 32bit driver を使えば、回避できます。
record&play ツールとして、firefox には selenium builder を使えば、protractor js フォーマットのテストケースはそのままできますので。活用すれば、時間の節約に。
selenium builder
ただ、できたケースはコードはあまり良くないし、select には作成できないので、これを locator の element(by.options()), by.repeater で自分で書くしかないです。
それでは、また。
--baseUrl="NEW URL" <- これでテスト対象の URL が変更できます。テストケースの中に browser.baseUrl から取得可能です。
--params.xxx.xxx=NEW VALUE <- もし、config js に pramas フィールドが追加されるなら、params の値を送れば、NEW VALUE が適用されます。
もし、一つだけのテストケースを実行したいなら、
--suites=SUITE NAME
--specs=TEST CASE FILE NAME
で、ターゲットスイート、テストケースファイルが実行できます。複数実行したい場合、 コマで区切れば、protractor がそのまま実行できます。
テスト結果のレポートは HTML バージョンは下記のライブラリをつかれば、簡単につくれます。スクリーンショット付きで。
package/protractor-html-screenshot-reporter
config js ファイルの onprepare 関数に Jasmine の reporter を設定すれば、自動でフォルダに HTML と画面キャプチャーが作成されます。
あと、selenium sever をサーバーのものを使いたいなら、
--seleniumAddress を使えば、どこかのサーバーアドレスに設定できます。localhost じゃなくて。
注意すべきところは、リモートサーバーを使いたいなら、タイムアウト時間をちょっと長めに設定したほうがいいです。
これも Jasmine のものと合わせて、config js ファイルに
allScriptsTimeout: 30000 <- WebDriver の script タイムアウト時間を 30 秒に設定
jasmineNodeOpts: {defaultTimeoutInterval: 30000} <- Jasmine timeout を 30秒に設定
あと、ページタイムアウト、これを browser.get(url, time) 第二の引数に設定するも可能です。
getPageTimeout:30000
どのブラウザーでテストするには、capabilities, multi-capabilities で設定できるので、注意は一つ。
IE の場合、IEDriver の問題で 64bit が超遅いです。IE 11も対応してないので、IE10 + 32bit driver を使えば、回避できます。
record&play ツールとして、firefox には selenium builder を使えば、protractor js フォーマットのテストケースはそのままできますので。活用すれば、時間の節約に。
selenium builder
ただ、できたケースはコードはあまり良くないし、select には作成できないので、これを locator の element(by.options()), by.repeater で自分で書くしかないです。
それでは、また。
ローカル 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 で表示できる。
いろいろ考えてみると、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 アプリも作れるので、どんどん良くなっています。
それでは。
登録:
投稿 (Atom)