HAKASHUN / manabi

manabi
14 stars 1 forks source link

Angularのパフォーマンス文献 #46

Open HAKASHUN opened 10 years ago

HAKASHUN commented 10 years ago

http://daginge.com/technology/2013/08/11/debugging-performance-problems-in-angularjs-with-batarang/

HAKASHUN commented 10 years ago

http://stackoverflow.com/questions/9682092/databinding-in-angularjs

HAKASHUN commented 10 years ago

やはり、双方向データバインディングはかなりパフォーマンス的に問題あり 本当に必要なときだけ、Angularの便利機能を使うという考え方にたたないと、後で大変だ...

HAKASHUN commented 10 years ago

http://www.bennadel.com/blog/2548-don-t-forget-to-cancel-timeout-timers-in-your-destroy-events-in-angularjs.htm

Unfortunately, people seem to treat the $timeout() function in AngularJS as a set-it and forget-it type of function. But, forgetting about your $timeout callback can have negative consequences, all the way from code that fails silently to code that raises an exception to code that makes repeated $http requests to your server for no reason. The trick to managing your $timeout timers properly is to cancel them in your $destroy events.

HAKASHUN commented 10 years ago

$timeoutを使うとdigestLoopが走ってしまう

Angularの実装

https://github.com/angular/angular.js/blob/master/src/ng/timeout.js#L35-L59

$timeoutを使うときは、digest loopを意識して、必要なとき以外は、明示的にfalseを渡すか、setTimeoutを用いるべき

HAKASHUN commented 10 years ago

http://atsumo.hatenablog.com/entry/2014/08/05/153256

上記の第4引数のパラメーターに$rootScope.apply()を行わないためのbooleanを入れることができるが、$rootScope.apply()は避けられても、 $interval内部で行われているdefferで$evalAsyncを読んでるため、結果タイミングはscopeが更新されてしまうっていう・・・w

$intervalは不可避?

HAKASHUN commented 10 years ago

$timeoutと$intervalのinvokeapplyのバグ対応

https://github.com/angular/angular.js/commit/19b6b3433ae9f8523cbc72ae97dbcf0c06960148

HAKASHUN commented 10 years ago

Superspeed your angularjs apps

But when rendering large DOM trees like containing tables with sort able columns, filtering and stuff ... it might get slower than you want ...

  • やはりAngularJSでフィルタとかソート駆使すると重いよね...

The hints detailed in this article can improve AngularJS pages rendering up to 1000% and more - no kidding !

  • 1000%もレンダリングはやくするらしい...

If you read the excellent answer over at Stackoverflow: Databinding in angularjs then you might noticed that AngularJS compares the last rendered data with the current datamodel whenever $apply was called to evaluate which parts of the DOM must be updated.

  • $applyされるとき現在のデータモデルと最後にレンダリングされるでーたを比べるからいけないみたい

Where are the bottlenecks ?

  • If you open the jsFiddle example in a new browser window with opened Javascript console you will see that function getEntries() will be called 2 times. But ist just a single reference to getEntries in the template, correct ? The reason is that AngularJS renders the page and then checks if the rendered data was changed while rendering (Remember, your data model may change while rendering : see ng-init).
  • Whenever you type in some data in the label/value INPUT fields AngularJS will again check if the rendered data was changed.
  • If you change the item order, AngularJS will again check if the rendered data was changed.
<div ng-repeat="entry in getEntries() | orderBy:order">

The solution

The single point slowing down performance is the repeated call to getEntries() and the orderBy filter. The solution to our problem is simple : We can cache the ordered entries !

  • 問題を解決できるらしい...期待。

To not reinvent the wheel we take the exceptional excellent lodash library to help us implement caching. lodash is used to

  • order items using _.sortBy instead of the AngularJS orderBy filter
  • cache the resulting sorted item list using _.memoize.
  • filter使うのをやめて、lodashの_.memoizeを使おう!ということらしい。
  • _.memoizeの第1引数は、配列を返す関数で、第2引数はcacheKeyを返す関数
  • リストが変更されたら、キャッシュをクリアすれば問題ないらしい。

サンプルを見る限り、getEntries関数は無駄に複数呼ばれていない! すごい!!!

HAKASHUN commented 10 years ago

_.memoizeを使ってみた結果

扱っているプロダクトで、memoizeを使えそうな箇所があったので対応してみたので感想を。

<div ng-repeat="entry in getEntries()">

このように、テンプレートにfunctionを定義すると、memoizeで実装した関数は複数回実行されてしまう。

なので、

<div ng-repeat="entry in entries">

このようにテンプレートに表示したいアイテム配列を渡してあげた方が良い。 しかるべきタイミングで、表示アイテムを変更するときは、コントローラ内で行うようにしたらいい。

HAKASHUN commented 10 years ago

data-bindingについて深く知る

http://stackoverflow.com/questions/9682092/databinding-in-angularjs/9693933#9693933