Angular銀行向けに構築しているアプリを使用して、パフォーマンスの問題に頭を打ちつけています。
残念ながら、コードのスニペットを表示することは契約違反です。とにかく、進行中の主な問題のいくつかを説明できますが、ベストプラクティスが推奨されることを望んでいます。
アプリケーション構造:
タイムラインを見ると。 jQuery解析htmlメソッド、jQuery再計算styeメソッド、GCイベント(ガベージコレクション)に多くの時間を費やしています。これらを最小化すると、少し速度が上がると思います。これらはすべてAngularライフサイクルの一部ですが、それらを回避するためのより良い方法があるかもしれません。プロファイラのスクリーンショットは次のとおりです。
最終的に、繰り返されるフォームの数が5を超えると、アプリは遅くなります。各フォームは他のフォームとは比較的無関係です。フォーム間で共有プロパティを監視しないようにしました。
Angularのパフォーマンスの問題を抑えるために、カスタムディレクティブを作成する必要があります。 ember angularには、すべての機能がオンになっているので、トーンを下げるのはあなた次第です。以下に、いくつかのディレクティブを作成しました。アプリ内のすべてのデータが双方向のデータバインドである必要はありません。その結果、必要に応じてページ内の監視式を省略することで、貴重なCPUパワーを節約できます。
https://Gist.github.com/btm1/6802599
https://Gist.github.com/btm1/6802312
https://Gist.github.com/btm1/674615
上記の回答の1つは、ng-repeatがパフォーマンスに大きな影響を与えることについて説明しているため、「set-repeat」に1回限りのデータバインディングリピートディレクティブを指定します。
あなたの問題に関する詳細な情報なしで解決策を提供することは難しいですが、私は最近経験しました(そして解決しました) パフォーマンスの問題 これはあなたが見たものと似ているかもしれず、$ digestサイクルとは無関係でした。
Miskoの優れた投稿 を含む、angularjsのパフォーマンスに関するほとんどの議論は、ダーティチェックと$ digestサイクルのパフォーマンスについてです。しかし、angularjsで発生する可能性のあるパフォーマンスの問題はそれだけではありません。最初のステップは、ダイジェストサイクルが問題かどうかを判断することです。このためには、batarangを使用するか、アプリを見て、正確に動作が遅いときを見ることができます。ダイジェストサイクルが遅い場合、基本的にUIとの対話は遅くなります。
OTOH、高速なダイジェストサイクルを備えたアプリを使用できます。これは、読み込み、ビューの切り替え、または表示するコンポーネントのセットを変更する場合にのみ遅くなります。収集します。私の場合、これは、どこでもng-repeat、ng-switch、ng-ifに依存するのではなく、表示するhtmlテンプレートの事前計算を行うことで解決しました。
ウィジェットの種類のngスイッチを含むng-repeat = "widget in widgets"を使用して、任意のウィジェットセット(カスタムの自己完結型ディレクティブ)を表示していました。これをコードで置き換えて、ウィジェットの特定のセット用にangularテンプレートを生成し、ルートの切り替えを10秒から実質的に瞬時に高速化しました。
特定の問題をどのように解決したかの詳細については、上記のGoogleグループスレッドをご覧ください。具体的な提案が必要な場合は、アプリケーションに関する詳細情報を提供してください。
本番環境でのパフォーマンスを向上させるには、以下の非常に素晴らしいワンライナーをお読みください。
AngularJSドキュメントの引用:
デフォルトでは、AngularJSはバインディングとスコープに関する情報をDOMノードに添付し、CSSクラスをデータバインド要素に追加します。
NgBind、ngBindHtmlまたは{{...}}補間の結果として、バインディングデータとCSSクラスng-bindingが対応する要素に付加されます。
コンパイラが新しいスコープを作成した場合、スコープとng-scopeまたはng-isolated-scope CSSクラスが対応する要素に添付されます。これらのスコープ参照は、element.scope()およびelement.isolateScope()からアクセスできます。
ProtractorやBatarangなどのツールを実行するにはこの情報が必要ですが、本番環境ではこれを無効にして、パフォーマンスを大幅に向上させることができます。
myApp.config(['$compileProvider', function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}]);
詳細を読むことができます こちら
一般に、2000個を超えるデータバインディングがアクティブな場合、つまり、$ digestサイクルごとにダーティチェックされているスコープ内の2000個のアイテムがある場合、AngularJSのパフォーマンスは低下します。これにより、ng-repeatはパフォーマンスに大きな影響を与えます。繰り返される各アイテムは、少なくとも2つのバインディングを設定し、アイテム内で使用される追加のデータまたはディレクティブをカウントしません。
AngularJSの背後にいる開発者の1人が、ダーティチェックの詳細とそのパフォーマンスについて優れた説明を提供していますSO answer:
https://stackoverflow.com/a/9693933/179024
その答えの下のコメントスレッドは一読する価値があり、同じページのさらに下の答えでそれについての考えを共有します。
コメントをするのに十分なポイントがないので、それを「答え」として入れてすみません。
AngularJSアプリでも同様の問題が発生しました。 'batarang'を使用すると、多数のスコープオブジェクトを処理する必要があり、関連する$ watch式がパフォーマンスの問題を引き起こします。これにより、「ビュー」の部分を処理するために、代わりに別のフレームワークまたはReactJSのようなものを使用すべきかどうか疑問に思うようになりました。
以下を避けてみてください
ng-click、ng-mouseenter、ng-mouseleaveなどのマウスイベントは、必要になるまで盲目的に使用しないでください。jsのイベント伝播概念とともに$ eventオブジェクトを使用して、その数を減らしてください。
scope。$ watchの代わりにscope。$ digestを可能な限り使用します。これにより、ダイジェストサイクルが子スコープでのみ実行されます。
最も重要です!HTMLからすべてのフィルターを削除してください!
上記のすべてがアプリケーションのすべてのスコープでダイジェストサイクルをトリガーするため、ビューがレンダリングされた場合でもangularが容赦ないダイジェストループを実行している可能性が高い
DOM操作をカスタムディレクティブに移動することと、多くの$ watchesでの$ watchの問題の中間点は、「バインド1回」のセマンティクスを使用することです。
これは、データが使用可能になったら不変であるデータに最適です。 bindonce を参照してください
これはリンクのみです!これは私がこれを読んでいたときに持っていたアイデアであり、まだ調査していませんが、おそらく誰かがやったので、私のアイデアについての回答を待っています。共有Webワーカーを使用して、UIスレッドから大量の重い処理を取得するのはどうですか? https://github.com/h2non/sharedworkers-angular-poc
私が持っていた他のアイデアは、よりシンプルなものでした。アプリは無限スクロールの恩恵を受けますか?これらのフォームはおそらく画面に収まらないので、互いに接続されていないので、必要に応じてそれらを描画してみませんか?それらをメモリにロードし、それに応じて描画します。
他のパフォーマンス最適化と同様に、アプリケーションをプロファイリングして真のボトルネックを見つける方法を知ることが重要です。その後、それらを1つずつ解決できます。私は通常、次の順序でボトルネックと戦います。
angular各ステップでボトルネックを特定する方法を示すステップバイステップの例。 http://bahmutov.calepin.co/improving-angular-web-app- performance-example.html