ng-ifとng-show / ng-hideのどちらを優先するのですか?


516

私がいることを理解ng-showし、ng-hide要素のクラス集合とその影響を与えるng-if要素はDOMの一部としてレンダリングされているかどうかを制御します。

選択のガイドラインがあるng-ifオーバーng-show/ ng-hideまたはその逆は?



1
dart言語とは関係ありません。
naXa

回答:


703

ユースケースに依存しますが、違いを要約すると:

  1. ng-ifDOMから要素を削除します。これは、すべてのハンドラー、またはそれらの要素にアタッチされているその他すべてが失われることを意味します。たとえば、クリックハンドラーをいずれかの子要素にバインドした場合、ng-if評価がfalseの場合、その要素はDOMから削除され、ng-if後でtrueと評価されて要素が表示された後でも、クリックハンドラーは機能しなくなります。ハンドラーを再接続する必要があります。
  2. ng-show/ng-hideDOMから要素を削除しません。CSSスタイルを使用して要素を非表示/表示します(注:独自のクラスを追加する必要がある場合があります)。このようにして、子にアタッチされたハンドラーは失われません。
  3. ng-if子スコープを作成しますが、作成しng-show/ng-hideません

DOMにない要素はパフォーマンスへの影響が少なく、Webアプリケーションはng-ifと比べて使用した方が高速に見える場合がありますng-show/ng-hide。私の経験では、その違いはごくわずかです。ng-show/ng-hideとの両方を使用するとng-if、アニメーションが可能になります。Angularのドキュメントに両方の例があります。

最終的に、答える必要がある質問は、DOMから要素を削除できるかどうかです。


19
でCSS3アニメーションを使用できますng-if。アニメーションの段落とドキュメントの例を確認してください。また、非表示の要素もカウントされるためng-hide/ng-show、CSSセレクターと同様に、:first-childまたは:nth-child正しく機能しません。
–ŁukaszWojciechowski 14

4
angular.dartのアニメーションサービスは比較的新しいものです。これを書いている時点では利用できませんでした。
markovuksanovic 14年

44
必要に応じて、ハンドラーをバインドするためにディレクティブ(ng-clickなど)を使用している場合、最初のポイントは問題ではありません。
Kevin C.

9
また、ng-if作成しng-showませんが、新しいスコープを作成します。
火曜日、2014年

8
また、DOMへの要素の追加と削除を頻繁に行うと、高いパフォーマンスコストが発生する可能性があることにも注意してください。
Kevin C.

130

ng-if / ng-showの動作の違いをDOMごとに示すCodePen については、こちらをご覧ください。

@markovuksanovicは質問によく答えました。しかし、私は別の見方からそれを思いつきます。私は常に以下の場合ng-ifを除いて、DOMからこれらの要素を使用して取得します。

  1. 何らかの理由$watchで、要素のデータバインディングと-esが非表示になっている間もアクティブのままにしておく必要があります。フォーム全体が有効かどうかを判断するために、現在表示されていない入力の有効性を確認できるようにする場合は、フォームがこれに適したケースである可能性があります。
  2. 上記のように、条件付きイベントハンドラーを使用して、非常に精巧なステートフルロジックを使用しています。とは言っても、ng-ifを使用すると重要な状態が失われるなど、手動でハンドラーをアタッチおよびデタッチする場合は、その状態がデータモデルでより適切に表現され、ハンドラーはいつでもディレクティブによって条件付きで適用されるかどうかを自問してください要素がレンダリングされます。言い換えれば、ハンドラーの有無は、状態データの一種です。そのデータをDOMから取り出してモデルに入れます。ハンドラーの有無はデータによって決定されるため、簡単に再作成できます。

Angularは本当によく書かれています。それが何をするかを考えると、それは速いです。しかし、それが行うのは、(2方向データバインディングなどの)難しいことを簡単に見せる魔法の束です。これらすべてを簡単に見せるには、パフォーマンスのオーバーヘッドが伴います。$digest誰も見ないDOMの塊で、サイクル中にセッター関数が何百回または何千回も評価されることに驚かれるかもしれません。そして、あなたは何十、何百もの見えない要素がすべて同じことをしていることに気づきます...

実際、デスクトップは、ほとんどのJS実行速度の問題を解決するのに十分強力な場合があります。ただし、モバイル向けに開発している場合、人間が可能な限りng-ifを使用することは簡単です。JSの速度は、モバイルプロセッサでも重要です。ng-ifを使用すると、非常に低いコストで、潜在的に重要な最適化を簡単に実現できます。


6
上記の答えに非常に素晴らしい追加。適切なコンテキストが与えられているため、意思決定にも役立ちます。ありがとう。
ショーン

1
ng-showレンダリングに時間がかかる多くのコンテンツを含むタブがある場合に便利です。最初のレンダリング後、タブ間の移動は瞬時になりますng-ifが、再レンダリング、イベントのバインドなどが必要になります。言うと、バックグラウンドで実行されるウォッチが作成されます。Angularは必死に必要ng-ifshowwatch
最高の

53

私の経験から:

1)ページにng-if / ng-showを使用して何かを表示/非表示にするトグルがある場合、ng-ifはブラウザーの遅延を長くします(遅くします)。例:2つのビューを切り替えるために使用されるボタンがある場合、ng-showの方が高速であるように見えます。

2)ng-ifは、true / falseと評価されたときにスコープを作成/破棄します。ng-ifにコントローラーが接続されている場合、ng-ifがtrueと評価されるたびにそのコントローラーコードが実行されます。ng-showを使用している場合、コントローラーコードは1回だけ実行されます。したがって、複数のビューを切り替えるボタンがある場合、ng-ifとng-showを使用すると、コントローラーコードの記述方法に大きな違いが生じます。


5
それは本当だ!ng-ifは必ずしもフロントエンドを高速にするわけではありません。それはあなたのニーズに依存します。実際、間違った状況で使用している場合は、逆になる可能性があります。
Thiago C. S Ventura

1
しかし私によると、ng-ifはDOMにレンダリングされないため、ng-show / hideに比べて高速です。私は間違っていますか?
Pardeep Jain、2015

1
ng-ifがfalseと評価された場合は、DOMに何も挿入する必要がないため、処理が速くなります。しかし、それが真実である場合、DOMに-おそらく非常に複雑な-要素を挿入するオーバーヘッドがあります。
Mawgはモニカを2016

"2)ng-ifはtrue / falseと評価されたときにスコープを作成/破棄します。ng-ifにコントローラーが接続されている場合、コントローラーコードは毎回実行されます"
The Red Pea

35

答えは単純ではありません。

それはターゲットマシン(モバイルとデスクトップ)に依存し、データの性質、ブラウザー、OS、実行するハードウェアに依存します。本当に知りたい場合は、ベンチマークを行う必要があります。

ほとんどのメモリと計算の問題です...ほとんどのパフォーマンスの問題と同様に、リストのような要素(n)が繰り返されると、特にネストされた場合(nxn、またはそれより悪い場合)、およびこれらの要素内で実行する計算の種類が大きくなるため、違いが大きくなる可能性があります。:

  • ng-show:それらのオプションの要素がしばしば存在する(密である)場合、たとえば90%の時間のように、それらを準備して表示/非表示にする方が速い場合があります。特に、コンテンツが安い場合(プレーンテキストのみ、何もない場合)計算またはロード)。非表示の要素でDOMを埋めるため、これはメモリを消費しますが、既に存在するものを表示/非表示にするだけで、ブラウザの負荷が軽減される可能性があります。

  • ng-if:逆に要素が表示されない(スパース)可能性が高い場合は、それらを構築してリアルタイムで破棄します。特に、コンテンツの取得にコストがかかる場合(計算/並べ替え/フィルター処理、画像、生成された画像)。これは、まれな要素または「オンデマンド」要素に最適です。DOMを埋めないという点でメモリを節約できますが、多くの計算(要素の作成/破棄)と帯域幅(リモートコンテンツの取得)が必要になります。また、ビューで計算する量(フィルタリング/並べ替え)と、モデルに既にあるもの(事前に並べ替え/事前にフィルタリングしたデータ)にも依存します。


2
技術的事実に関するその他の回答。これは知恵のためです。自明ではないAngularアプリを作成しました!+1
2016

この問題は角度を超えたものであり、コンピュータサイエンスの根本的な問題であり、1つの方法が他の方法よりも効率的であるという点があります。通常、これはいくつかのベンチマークを通じて見つけることができます。あなたも一つの方法と項目数に応じて、他の間で切り替えることができるように...同様のトピック:math.stackexchange.com/questions/1632739/...
クリストフRoussy

12

重要な注意点:

ngIf(ngShowとは異なり)は通常、予期しない結果を生成する可能性がある子スコープを作成します。

これに関連する問題があり、何が起こっているのかを理解するのにかなりの時間を費やしました。

(私のディレクティブは、モデル値を間違ったスコープに書き込んでいました。)

そのため、実行速度が遅すぎない限り、髪を節約するにはngShowを使用してください。

とにかくパフォーマンスの違いはほとんど気づかれず、テストなしで誰が有利かはまだわかりません...


8
使用$parent.scopevar中のデータバインディングにngIf使用した場合、子のスコープの問題のようなものを修正しますngIfを
meconroy

2
これは完全に真実ではありません(元の@ user2173353のコメント、つまり)。あなたが良い習慣に固執すれば、トラブルに巻き込まれることはありません。それはかなり基本的なルールです:「ドットがない場合、あなたはそれを間違っています」。動作のデモについては、ここを参照してください:bit.ly/1SPv4wL。もう1つの優れたリファレンス(間違い#2を参照):bit.ly/1QfFeWd >(私のディレクティブはモデル値を間違ったスコープに書き込んでいました。)これは、上記の方法に固執しない結果です。
piotr.d 2015年

1
@ piotr.dあなたは正しいですが、初心者が集中する必要があるかもしれないものではなく、最後にパフォーマンスの改善を残すことをお勧めする別のベストプラクティスがあります(特に、実際には改善されない可能性があるパフォーマンスの改善) )。ngIfこれがパフォーマンスを向上させると信じてどこにでも置く人々を見てきました。これは単に真実ではなく、特定のケースでのテストまたは詳細な分析なしでは、どれが最良であるngIfngShow、またはであるかは言えません。ですから、ngIfパフォーマンスの低下が見られるか、彼が何をしているのかがわかるまでは、を忘れることをお勧めします
user2173353

2
いい視点ね。しかし、controllerAsを使用すると、これは問題になりません。たとえば、John PapaによるcontrollerAsとvmのテイクを参照してください。
jsruok 2016

4

ng-includeとng-controllerのng-ifは、ng-includeに大きな影響を及ぼします。必要なパーシャルをロードせず、フラグがtrueでない限り処理しませんng-controllerでフラグがtrueでない限り、コントローラーをロードしませんtrueですが、問題は、フラグがng-falseになると、フラグはDOMから削除され、フラグがtrueになると、DOMをリロードします。この場合、ng-showの方が優れています。


4

あなたが使用している場合はng-show or ng-hide、コンテンツを(例えば、サーバからサムネイル)式の値にかかわらずロードされますが、式の値に基づいて表示されます。

ng-ifコンテンツを使用する場合、ng-ifの式が真と評価された場合にのみロードされます。

ng-ifの使用は、サーバーからデータまたは画像をロードし、ユーザーの操作に応じてそれらのみを表示する場合に適しています。このようにして、ページの読み込みが不要なnw集中タスクによってブロックされることはありません。


CSSがDOMコンテナーを隠している場合でも、ほとんどのブラウザーは画像を読み込むため、これは特に便利です。通常srcimgタグの属性を探し、存在する場合は読み込まれます。
Christophe Roussy、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.