Skip to content

Commit 07b9181

Browse files
committed
feat: skipping-subtrees.mdの翻訳
1 parent 0464588 commit 07b9181

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# コンポーネントサブツリーをスキップする
2+
3+
JavaScriptは、デフォルトでは、複数の異なるコンポーネントから参照できる可変データ構造を使用します。Angularは、データ構造の最新の状態がDOMに反映されるように、コンポーネントツリー全体で変更検知を実行します。
4+
5+
変更検知は、ほとんどのアプリケーションにとって十分に高速です。ただし、アプリケーションが特に大きなコンポーネントツリーを持っている場合、アプリケーション全体で変更検知を実行すると、パフォーマンスの問題が発生する可能性があります。これは、コンポーネントツリーのサブセットでのみ変更検知が実行されるように構成することで対処できます。
6+
7+
アプリケーションの一部が状態変化の影響を受けないと確信できる場合は、[OnPush](/api/core/ChangeDetectionStrategy)を使用して、コンポーネントのサブツリー全体の変更検知をスキップできます。
8+
9+
## `OnPush`の使用
10+
11+
OnPush変更検知は、Angularにコンポーネントのサブツリーの変更検知を次の場合**のみ**実行するように指示します。
12+
13+
* サブツリーのルートコンポーネントが、テンプレートバインディングの結果として新しいinputを受け取った場合。Angularは、inputの現在と過去の値を`==`で比較します。
14+
* Angularが、OnPush変更検知を使用しているかどうかに関係なく、サブツリーのルートコンポーネント、または、その子でイベント *(例えば、イベントバインディング、outputバインディング、または`@HostListener`を使用)* を処理する場合。
15+
16+
コンポーネントの変更検知戦略を`@Component`デコレーターで`OnPush`に設定できます。
17+
18+
```ts
19+
import { ChangeDetectionStrategy, Component } from '@angular/core';
20+
@Component({
21+
changeDetection: ChangeDetectionStrategy.OnPush,
22+
})
23+
export class MyComponent {}
24+
```
25+
26+
## 一般的な変更検知のシナリオ
27+
28+
このセクションでは、Angularの動作を説明するために、いくつかの一般的な変更検知のシナリオを検証します。
29+
30+
### デフォルトの変更検知を持つコンポーネントによってイベントが処理される場合
31+
32+
Angularが`OnPush`戦略なしでコンポーネント内でイベントを処理する場合、フレームワークはコンポーネントツリー全体で変更検知を実行します。Angularは、新しいinputを受け取っていない、`OnPush`を使用しているルートを持つ子孫コンポーネントのサブツリーをスキップします。
33+
34+
例として、`MainComponent`の変更検知戦略を`OnPush`に設定し、ユーザーがルート`MainComponent`を持つサブツリーの外部のコンポーネントとやり取りする場合、`MainComponent`が新しいinputを受け取らない限り、Angularは下の図のすべてのピンク色のコンポーネント(`AppComponent``HeaderComponent``SearchComponent``ButtonComponent`)をチェックします:
35+
36+
```mermaid
37+
graph TD;
38+
app[AppComponent] --- header[HeaderComponent];
39+
app --- main["MainComponent (OnPush)"];
40+
header --- search[SearchComponent];
41+
header --- button[ButtonComponent];
42+
main --- login["LoginComponent (OnPush)"];
43+
main --- details[DetailsComponent];
44+
event>Event] --- search
45+
46+
class app checkedNode
47+
class header checkedNode
48+
class button checkedNode
49+
class search checkedNode
50+
class event eventNode
51+
```
52+
53+
## OnPushを持つコンポーネントによってイベントが処理される場合
54+
55+
AngularがOnPush戦略を持つコンポーネント内でイベントを処理する場合、フレームワークはコンポーネントツリー全体で変更検知を実行します。Angularは、新しいinputを受け取っておらず、イベントを処理したコンポーネントの外部にある、OnPushを使用しているルートを持つコンポーネントのサブツリーを無視します。
56+
57+
例として、Angularが`MainComponent`内でイベントを処理する場合、フレームワークはコンポーネントツリー全体で変更検知を実行します。Angularは、ルートである`LoginComponent`を持つサブツリーを無視します。これは、`LoginComponent``OnPush`を持ち、イベントがそのスコープ外で発生したためです。
58+
59+
```mermaid
60+
graph TD;
61+
app[AppComponent] --- header[HeaderComponent];
62+
app --- main["MainComponent (OnPush)"];
63+
header --- search[SearchComponent];
64+
header --- button[ButtonComponent];
65+
main --- login["LoginComponent (OnPush)"];
66+
main --- details[DetailsComponent];
67+
event>Event] --- main
68+
69+
class app checkedNode
70+
class header checkedNode
71+
class button checkedNode
72+
class search checkedNode
73+
class main checkedNode
74+
class details checkedNode
75+
class event eventNode
76+
```
77+
78+
## OnPushを持つコンポーネントの子孫によってイベントが処理される場合
79+
80+
AngularがOnPushを持つコンポーネントでイベントを処理する場合、フレームワークはコンポーネントの祖先を含め、コンポーネントツリー全体で変更検知を実行します。
81+
82+
例として、下の図では、AngularはOnPushを使用する`LoginComponent`でイベントを処理します。Angularは、`MainComponent``OnPush`があるにもかかわらず、`MainComponent``LoginComponent`の親)を含め、コンポーネントのサブツリー全体で変更検知を呼び出します。Angularは、`LoginComponent`がそのビューの一部であるため、`MainComponent`もチェックします。
83+
84+
```mermaid
85+
graph TD;
86+
app[AppComponent] --- header[HeaderComponent];
87+
app --- main["MainComponent (OnPush)"];
88+
header --- search[SearchComponent];
89+
header --- button[ButtonComponent];
90+
main --- login["LoginComponent (OnPush)"];
91+
main --- details[DetailsComponent];
92+
event>Event] --- login
93+
94+
class app checkedNode
95+
class header checkedNode
96+
class button checkedNode
97+
class search checkedNode
98+
class login checkedNode
99+
class main checkedNode
100+
class details checkedNode
101+
class event eventNode
102+
```
103+
104+
## OnPushを持つコンポーネントへの新しいinput
105+
106+
Angularは、テンプレートバインディングの結果としてinputプロパティを設定するときに、`OnPush`を持つ子コンポーネント内で変更検知を実行します。
107+
108+
例えば、下の図では、`AppComponent``OnPush`を持つ`MainComponent`に新しいinputを渡します。Angularは`MainComponent`で変更検知を実行しますが、`LoginComponent``OnPush`を持っている場合でも、新しいinputを受け取らない限り、`LoginComponent`では変更検知を実行しません。
109+
110+
```mermaid
111+
graph TD;
112+
app[AppComponent] --- header[HeaderComponent];
113+
app --- main["MainComponent (OnPush)"];
114+
header --- search[SearchComponent];
115+
header --- button[ButtonComponent];
116+
main --- login["LoginComponent (OnPush)"];
117+
main --- details[DetailsComponent];
118+
event>Parent passes new input to MainComponent]
119+
120+
class app checkedNode
121+
class header checkedNode
122+
class button checkedNode
123+
class search checkedNode
124+
class main checkedNode
125+
class details checkedNode
126+
class event eventNode
127+
```
128+
129+
## エッジケース
130+
131+
* **TypeScriptコードでinputプロパティを変更する**`@ViewChild``@ContentChild`のようなAPIを使用して、TypeScriptでコンポーネントへの参照を取得し、`@Input`プロパティを手動で変更すると、AngularはOnPushコンポーネントの変更検知を自動的に実行しません。Angularに変更検知を実行させる必要がある場合は、コンポーネントに`ChangeDetectorRef`を注入し、`changeDetectorRef.markForCheck()`を呼び出して、Angularに変更検知をスケジュールするように指示できます。
132+
* **オブジェクト参照の変更**。inputが可変オブジェクトを値として受け取り、オブジェクトを変更しても参照を保持する場合、Angularは変更検知を呼び出しません。これは、inputの以前の値と現在の値が同じ参照を指しているため、予期される動作です。

0 commit comments

Comments
 (0)