投稿

ラベル(AngularJS)が付いた投稿を表示しています

これがAngularJSの$apply()や$digest()が低速な理由のひとつか?

イメージ
昨日書いた記事 「 琴線探査: Dr. GlebのAngularアプリ最適化TIPSまとめ 」 ã«、try-catchがあるとV8では最適化されないため処理が遅くなると書いた。 今日は自分で書いたアプリをプロファイルしてみた。このように、$apply()や$digest()に相当な時間がかかっていることが分かった。 これは予想通りだったが、驚いたのは$apply()や$digest()でtry-catchを使っているらしいことだ。 「Not optimized: TryCatch Statement」とツールチップが出ている。ひょっとすると、これが$apply()や$digest()が低速な理由のひとつなのかもしれない。 だとすると、かなり根本的なレベルで高速化できていないことになる…内部的にtry-catchを使わないようにできないのかなぁ(´・ω・`)

Dr. GlebのAngularアプリ最適化TIPSまとめ

Dr. Glebのブログ記事 Improving Angular web app performance example. | Better world by better software を簡単にまとめておこうと思う。 try-catchはできるだけ使わない V8ではtry-catchを使った処理は最適化されないので、特にループ処理ではできるだけ使わないようにする。Primesの例ではtry-catchを無くしただけで全体の処理は2倍以上、メソッド単体では200倍近く高速化している。 追記15.08.26 :$apply()や$digest()でtry-catchが使われていることが判明(ノ∀`) 琴線探査: これがAngularJSの$apply()や$digest()が低速な理由のひとつか? ダイジェストサイクルをできるだけ速くする $scope.$apply()した時のあれ。ダイジェストサイクルはフレームレートと同じで、長くなるほどUIが固まってしまうことになる。短くする方法は色々ある。 バインドさせる変数をできるだけ少なくする ng-modelとか$scope.valueとか。バインドさせる変数の数だけダイジェストサイクルは遅くなる。 filterはできるだけ使わない filterはダイジェストサイクルを遅くさせる。「{{ "index" | lowercase }}」的な無駄なフィルターはもってのほか。 one-time-bindingを使う サーバーから持ってくるデータは大抵の場合は大量だ。これをページにレンダリングするために2wayバインディングを使ってしまうとダイジェストサイクルが大幅に遅くなる。 そこでAngular1.3から導入されたone-time-bindingを使う。これを使えば、始めだけはバインディングするのでダイジェストサイクルに影響するが、その後は影響が無くなる。 例えば「{{name}}」としている所を「{{::name}}」とするだけでone-time-bindingになる。 AngularJS: Developer Guide: Expressions React的なレンダリング方法に変更する 特にtableの中身などの反復...

Angular2.x系が出るまで1.x系でES6やTypeScriptと共存させる方法についてのビデオ

イメージ
Angular2.x系が出るまで1.x系でES6やTypeScriptと共存させるにはどうしたらよいのか? この疑問に、このビデオ「Getting Ready for Angular 2.0」がある程度答えてくれていたのでメモ。 55:34あたりからThe question is…「But What Do We Do Now?」と始まる。そう。そこが聞きたかった! ES6って何となく全く違う言語のような気がしていて、一体どんな風に書くの?と思っていた。 しかし、よくよく考えてみるとES6はES5の機能を受け継いでいるので、ES6で書いてもAngular1.x系は動くのである。というか、「ES5でES6の拡張機能が使えるようになったと考えた方がいい」ということに気づかされた。 例えば、これがおなじみの1.x系でのコントローラーの書き方だ。 そして、ES6と共存させて書くとこうなる。 より現実的には、このようにクラスをファイルに分けることになるだろう。 これを使う場合はこうなる。 その他、ディレクティブやNew Routerについてもメンションされている。 これらをヒントに、これからES6というかTypeScriptで書く実験をしてみたいと思う。 ES6はつい先日正式版になったばかりだ。ではES6を使い始めるのは一体いつか?それは今でしょう。 Thanks, Yuri Takhteyev!

angular.element()のjQueryを読み込んだ場合とそうでない場合(jqLite)の動作の違い

できるだけページを軽量化するためにjQueryを読み込まないようにしようと思った。しかし、jQueryは便利なので捨てがたいなと思っていた。そんな時、angular.element()というメソッドがあることに気がついた。 AngularJS: API: angular.element AngularJSは内部でjqLiteというjQueryのサブセット版を持っていて、angular.element()はそれを使ってjQueryのオブジェクトを返してくれるらしい。 ただ実際に使ってみると、jQueryを読み込んだ場合とそうでない場合で動作が違うのでハマった。 jQueryを読み込んでいる場合はこのように#targetを取得できるが、そうでない場合、つまりjqLiteのみの場合は取得できない。 var $elm = angular.element('#target'); 要するにjQueryを読み込んでいる場合は次と等価だ。 var $elm = $('#target'); 一方、jqLiteのみの場合はこのようにする。 var elm = document.getElementById('target'); var $elm = angular.element(elm); Wraps a raw DOM element or HTML string as a jQuery element. というのはそういう意味だったのか!とやっと分かった(^^);

ツイートボタンをリロードする(ページが読み込まれた後に動的に再作成する)には?

ツイートボタンはこのページで自由にカスタマイズして作成できる。 Twitter Buttons | About 作成したコードをページに埋め込むと、そのページをブラウザでロードしたときに表示されるのは知っての通り。 基本的にツイートするアドレスや内容などはページをロードする時に決まっている必要があるが、ページをロードした後でそれらを変更するにはどうしたらいいだろうか? ブログやホームページなどの静的なサイトで問題になることはあまりないだろうが、AngularJSなどで構築したシングルページアプリケーションでは大いに問題になり得る。 まず、ツイートボタンを表示するホルダーをこのように作成する。 <!-- ツイートボタンホルダー --> <div id="tweetButtonHolder"> </div> <!-- ツイートボタン作成サイト https://about.twitter.com/resources/buttons#tweet でコピーしたscriptタグ --> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> このscriptタグは window.twttr を生成する。このオブジェクトは様々なツイートボタンを作ることができる。 Scripting: Factory Functions | Tw...

AngularJSのコードをminify対応にするためのベストプラクティス

AngularJSはDependency Injectionをするので書き方によってはminifyした時にコードが破損してしまう場合がある。 例えばこのようなコードは破損する。 var app = angular.module('app', []); app.controller('AppCtrl', function ($scope, $location, $interval, $timeout) { } ベストプラクティスはこれ。(だと思う) var app = angular.module('app', []); app.controller('AppCtrl', ['$scope', '$location', '$interval', '$timeout', function ($scope, $location, $interval, $timeout) { } 面倒でもfunctionの引数の定義の通りをfunctionの前に記述する。 このことはAngularJS公式チュートリアルの「A Note on Minification」に書いてあった。 AngularJS: Tutorial: 5 - XHRs & Dependency Injection こちらにも同じ議論がある。 javascript - Angularjs minify best practice - Stack Overflow

Angular-Materialを動かすための最小限テンプレートサンプル

イメージ
最近Angular-Material(以下「AM」)を使ってみている。 material.angularjs.org AMはまだ開発の初期段階ではあるものの、すでに結構使える状態ではないかと思う。 しかし、まだドキュメントが不十分でとっつきにくい。デモページでソースコードが見られるようになってはいるものの、headの終端から始まっていてコード全体が見通しにくい。 結局、AMのリポジトリをクローンしてデモの中身を直接見に行かなければならなかった。 そこで、ここにAMを動かすための最小限テンプレートの例を書いておきたいと思う。最終的にはこのように表示される。 Angular-Materialコンポーネントのインストール まずは適当な場所にプロジェクトディレクトリをつくり、AMをインストールする。 # cd ~/git # mkdir AngularMaterialMin # cd AngularMaterialMin # bower install angular-material これで必要なモジュールが全て揃う。 index.html <!DOCTYPE html> <html ng-app="app" ng-controller="AppCtrl"> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" /...

PolymerとAngularJS、Material DesignとPaper Elements、そしてAngular-Materialの関係の整理

イメージ
PolymerとAngularJS、Material DesignとPaper Elements、そしてAngular-Materialの関係をざっくり整理してみたいと思う。 Polymer Welcome - Polymer PolymerはW3C標準のWeb Components(カスタムエレメント)を作るためのライブラリと言えるだろう。データバインディングの機能も持っている。 Data binding overview - Polymer AngularJS AngularJS — Superheroic JavaScript MVW Framework AngularJSはWebアプリを作成するための汎用ライブラリと言えるだろう。Polymerのように、AngularJSにもデータバインディングとカスタムエレメント(ディレクティブ)を作る機能がある。 Material Design Introduction - Material design - Google design guidelines Material DesignはGoogleが提唱しているデザインガイドライン。色やアニメーション、スペーシングなどが事細かに決められている。 Metrics & keylines - Layout - Google design guidelines これはむしろ、「デザインガイドライン」というより「デザイン規約」、もしくは「デザイン仕様」と言った方がいいかもしれない。 Papar Elements Material Designを実装した(規約・仕様に準拠した)コンポーネント(カスタムエレメント)集と言えるだろう。 Material Designのサイト内で実際のコンポーネント例としてPaper Elementsが使われていることから、少なくとも現状ではMaterial Design ≒ Paper Elementsと考えて良さそうだ。 Buttons - Components - Google design guidelines 実際に動くPaper ElementsはPolymerのサイトにある。(PolymerによるPaper Elements実装) Paper Ele...

AngularJSのカスタムディレクティブでHTMLタグのアトリビュートの変更で何かをするサンプル

AngularJSのカスタムディレクティブでHTMLタグのアトリビュートの変更で何かをするにはどうしたらいいだろう? ここではHTMLタグのdisabledが変更された時に何かをする場合を考える。 ポイントは$oberve()。 「$scope.$watch(attr.disabled, function(value){})」かなーと思ってたけどこれではダメで、「attr.$observe("disabled", function(){})」だった。

AngularJSのバインディングに連動したフォームの検証(日付ピッカー)

先日、AngularJSのバインディングに連動したフォームの検証(日付)サンプルを書いた。 琴線探査: AngularJSのバインディングに連動したフォームの検証(日付)サンプル しかし、HTML5のDATE型の入力はブラウザによって日付ピッカーが出たり出なかったりするので、HTML5に依存しない形で作ろうと考えた。 日付ピッカーは探すと色々あるけれど、AngularJSとBootstrapを使っているということでこちらを使わせていただくことにした。 Angular Bootstrap Datetime picker dalelotts/angular-bootstrap-datetimepicker · GitHub 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSをとりあえずやってみたい人のためのごく簡単なサンプル集を作った。 JavaScriptはほとんど使っていなくて、主にAngularJSの機能とHTML側のコーディングだけでできる。 JavaScriptやjQueryのDOM操作の経験者なら、AngularJSを使うことでいかに楽になるかが分かると思う。 琴線探査: AngularJSの値のバインディング(自動挿入)サンプル 琴線探査: AngularJSのバインディングに連動した要素の表示・非表示サンプル 琴線探査: AngularJSのバインディングに連動した要素の操作可・不可のサンプル 琴線探査: AngularJSのバインディングに連動したフォームの検証(NULLチェック)サンプル 琴線探査: AngularJSのバインディングに連動したフォームの検証(正規表現)サンプル 琴線探査: AngularJSのバインディングに連動したフォームの検証(日付)サンプル 琴線探査: AngularJSのバインディングに連動したフォームの検証(フォーム全体)サンプル 追記14.05.16 : 琴線探査: AngularJSのバインディングに連動したフォームの検証(日付ピッカー)

AngularJSのバインディングに連動したフォームの検証(フォーム全体)サンプル

AngularJSのバインディングに連動したフォームの検証(フォーム全体)サンプル。他にライブラリが要らないところがいいわな。 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSのバインディングに連動したフォームの検証(日付)サンプル

AngularJSのバインディングに連動したフォームの検証(日付)サンプル。いまいち動かないブラウザもあり。やっぱChromeがベスト。 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集 追記14.05.16 :HTML5に依存しない日付ピッカーバージョンも書いた 琴線探査: AngularJSのバインディングに連動したフォームの検証(日付ピッカー)

AngularJSのバインディングに連動したフォームの検証(正規表現)サンプル

AngularJSのバインディングに連動したフォームの検証(正規表現)サンプル。HTMLで正規表現パターンを指定できるってすごくね? 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSのバインディングに連動したフォームの検証(NULLチェック)サンプル

AngularJSのバインディングに連動したフォームの検証(NULLチェック)サンプル。requiredするだけでいけるぜ! 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSのバインディングに連動した要素の操作可・不可のサンプル

AngularJSのバインディングに連動した要素の操作可・不可のサンプル。jQueryなどを使うより断然簡単! 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSのバインディングに連動した要素の表示・非表示サンプル

AngularJSのバインディングに連動した要素の表示・非表示サンプル。jQueryなどを使うより断然簡単! 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSの値のバインディング(自動挿入)サンプル

AngularJSのバインディングでHTMLに値を自動挿入するサンプル。jQueryなどを使うより断然簡単! 琴線探査: AngularJSをとりあえずやってみたい人のための簡単サンプル集

AngularJSでフルスクリーンオーバーレイメニューを表示する

フルスクリーンオーバーレイメニューを作りたいと思って色々と調べていたら、このようなおもしろいページを見つけた。 Fullscreen Overlay Styles & Effects | Demo 1 こちらを参考に、AngularJSを使って似たようなものを作ってみた。 改善点としては ・メニュー項目が増えても閉じるボタンに被らないように ・メニュー項目が増えてもスクロールして選択できるように ・メニュー項目を選択したらメニューを閉じるように という感じ。 しかし、レイアウトの方法を変えたからなのかAngularJSを使うようにしたからなのか、アニメーションの感じがちょっと違うし遅い。 実際に使うときは回転アニメーションは外した方がいいかもしれない。

AngularJSで春分の日と秋分の日を計算する

これまでも春分の日と秋分の日を計算するプログラムはJava版、ActionScript版と書いてきたが、今度はJavaScript版を書いてみた。再検証する必要があったからだ。 この計算によると、2024年の春分の日は3月20日になるらしい。 しかし、この計算結果は絶対ではない。春分の日と秋分の日は、国立天文台によって毎年官報で発表され、計算結果よりもこの発表が優先される。 実際、計算結果では2012年の春分の日が21日、秋分の日が23日となっているが、現実にはそれぞれ20日と22日だった。 琴線探査: 2012年は惑星直列らしいぞ!何事も無ければいいけれど・・・ | 来年の秋分の日116年ぶり22日に 国立天文台 - 日経 とりあえず、直近の2014年と2015年は計算結果通りだ。 国立天文台 | 平成27å¹´(2015)暦要項を発表 春分の日と秋分の日はとにかくめんどくさい。いちいち毎年決めないで、決め打ちにしちゃったらどうなんでしょ?(^^);