web-dev-qa-db-ja.com

Angular JS Scaling&Performance

Angular銀行向けに構築しているアプリを使用して、パフォーマンスの問題に頭を打ちつけています。

残念ながら、コードのスニペットを表示することは契約違反です。とにかく、進行中の主な問題のいくつかを説明できますが、ベストプラクティスが推奨されることを望んでいます。

アプリケーション構造:

  • 基本的に、巨大なマルチフォームページ。
  • 各フォームは独自のパーシャルであり、ネストされたコントローラーとパーシャルは約3レベルの深さです。
  • 同じフォームがjsonオブジェクトのコレクションでng繰り返されます。
  • 各フォームは、繰り返されるオブジェクト/モデルにバインドされます。
  • ページ上の1〜200個のフォームをサポートすることになっています。

タイムラインを見ると。 jQuery解析htmlメソッド、jQuery再計算styeメソッド、GCイベント(ガベージコレクション)に多くの時間を費やしています。これらを最小化すると、少し速度が上がると思います。これらはすべてAngularライフサイクルの一部ですが、それらを回避するためのより良い方法があるかもしれません。プロファイラのスクリーンショットは次のとおりです。

Recalculate StyleGC Event

最終的に、繰り返されるフォームの数が5を超えると、アプリは遅くなります。各フォームは他のフォームとは比較的無関係です。フォーム間で共有プロパティを監視しないようにしました。

42
trevorewen

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回限りのデータバインディングリピートディレクティブを指定します。

21
btm1

あなたの問題に関する詳細な情報なしで解決策を提供することは難しいですが、私は最近経験しました(そして解決しました) パフォーマンスの問題 これはあなたが見たものと似ているかもしれず、$ digestサイクルとは無関係でした。

Miskoの優れた投稿 を含む、angularjsのパフォーマンスに関するほとんどの議論は、ダーティチェックと$ digestサイクルのパフォーマンスについてです。しかし、angularjsで発生する可能性のあるパフォーマンスの問題はそれだけではありません。最初のステップは、ダイジェストサイクルが問題かどうかを判断することです。このためには、batarangを使用するか、アプリを見て、正確に動作が遅いときを見ることができます。ダイジェストサイクルが遅い場合、基本的にUIとの対話は遅くなります。

OTOH、高速なダイジェストサイクルを備えたアプリを使用できます。これは、読み込み、ビューの切り替え、または表示するコンポーネントのセットを変更する場合にのみ遅くなります。収集します。私の場合、これは、どこでもng-repeat、ng-switch、ng-ifに依存するのではなく、表示するhtmlテンプレートの事前計算を行うことで解決しました。

ウィジェットの種類のngスイッチを含むng-repeat = "widget in widgets"を使用して、任意のウィジェットセット(カスタムの自己完結型ディレクティブ)を表示していました。これをコードで置き換えて、ウィジェットの特定のセット用にangularテンプレートを生成し、ルートの切り替えを10秒から実質的に瞬時に高速化しました。

特定の問題をどのように解決したかの詳細については、上記のGoogleグループスレッドをご覧ください。具体的な提案が必要な場合は、アプリケーションに関する詳細情報を提供してください。

8
jssebastian

本番環境でのパフォーマンスを向上させるには、以下の非常に素晴らしいワンライナーをお読みください。

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);
}]);

詳細を読むことができます こちら

4
Abbasi

一般に、2000個を超えるデータバインディングがアクティブな場合、つまり、$ digestサイクルごとにダーティチェックされているスコープ内の2000個のアイテムがある場合、AngularJSのパフォーマンスは低下します。これにより、ng-repeatはパフォーマンスに大きな影響を与えます。繰り返される各アイテムは、少なくとも2つのバインディングを設定し、アイテム内で使用される追加のデータまたはディレクティブをカウントしません。

AngularJSの背後にいる開発者の1人が、ダーティチェックの詳細とそのパフォーマンスについて優れた説明を提供していますSO answer:

https://stackoverflow.com/a/9693933/179024

その答えの下のコメントスレッドは一読する価値があり、同じページのさらに下の答えでそれについての考えを共有します。

https://stackoverflow.com/a/18381836/179024

3
MW.

コメントをするのに十分なポイントがないので、それを「答え」として入れてすみません。

AngularJSアプリでも同様の問題が発生しました。 'batarang'を使用すると、多数のスコープオブジェクトを処理する必要があり、関連する$ watch式がパフォーマンスの問題を引き起こします。これにより、「ビュー」の部分を処理するために、代わりに別のフレームワークまたはReactJSのようなものを使用すべきかどうか疑問に思うようになりました。

2
5122014009

以下を避けてみてください

  1. リストに一度に50を超える要素がある場合はng-repeatの使用を避け、手動による監視は避けてください
  2. ng-click、ng-mouseenter、ng-mouseleaveなどのマウスイベントは、必要になるまで盲目的に使用しないでください。jsのイベント伝播概念とともに$ eventオブジェクトを使用して、その数を減らしてください。

  3. scope。$ watchの代わりにscope。$ digestを可能な限り使用します。これにより、ダイジェストサイクルが子スコープでのみ実行されます。

    1. 入れ子になったスコープ、つまり1つの親コントローラー内に1つまたは2つのコントローラーを入れて、再利用可能なロジックを親に保持してみて、Uiルーターを使用しながらこれを入れ子状態で使用しました(ページの更新なしでURLの変更が必要な要件を満たすため)。

    最も重要です!HTMLからすべてのフィルターを削除してください!

上記のすべてがアプリケーションのすべてのスコープでダイジェストサイクルをトリガーするため、ビューがレンダリングされた場合でもangularが容赦ないダイジェストループを実行している可能性が高い

2
Rishul Matta

DOM操作をカスタムディレクティブに移動することと、多くの$ watchesでの$ watchの問題の中間点は、「バインド1回」のセマンティクスを使用することです。

これは、データが使用可能になったら不変であるデータに最適です。 bindonce を参照してください

1
user239558

これはリンクのみです!これは私がこれを読んでいたときに持っていたアイデアであり、まだ調査していませんが、おそらく誰かがやったので、私のアイデアについての回答を待っています。共有Webワーカーを使用して、UIスレッドから大量の重い処理を取得するのはどうですか? https://github.com/h2non/sharedworkers-angular-poc

私が持っていた他のアイデアは、よりシンプルなものでした。アプリは無限スクロールの恩恵を受けますか?これらのフォームはおそらく画面に収まらないので、互いに接続されていないので、必要に応じてそれらを描画してみませんか?それらをメモリにロードし、それに応じて描画します。

0
Zoneh

他のパフォーマンス最適化と同様に、アプリケーションをプロファイリングして真のボトルネックを見つける方法を知ることが重要です。その後、それらを1つずつ解決できます。私は通常、次の順序でボトルネックと戦います。

  • 私のjavascriptコード
  • 各アイドルダイジェストサイクルで実行される角度表現(複雑なウォッチャーとフィルター)
  • 角構造(ng-repeat、ダイジェストサイクル用のオブジェクトのコピー)

angular各ステップでボトルネックを特定する方法を示すステップバイステップの例。 http://bahmutov.calepin.co/improving-angular-web-app- performance-example.html

0
gleb bahmutov