エラー百科辞典

Tracking expression caused re-creation of the DOM structure.

@for ループで指定されたアイデンティティトラック式が、_すべての_アイテムに対応するDOMの再作成を引き起こしました。これは、イミュータブルなデータ構造を扱う際に発生する一般的な操作で、非常に高価です。例:

      
@Component({  template: `    <button (click)="toggleAllDone()">All done!</button>    <ul>    @for (todo of todos; track todo) {      <li>{{todo.task}}</li>    }    </ul>  `,})export class App {  todos = [    { id: 0, task: 'understand trackBy', done: false },    { id: 1, task: 'use proper tracking expression', done: false },  ];  toggleAllDone() {    this.todos = this.todos.map(todo => ({ ...todo, done: true }));  }}

この例では、アイテムの "done" ステータスを切り替えた後、すべてのビュー(DOMノード、Angularディレクティブ、コンポーネント、クエリなど)を含むリスト全体が再作成されます(!)。ここでは、done プロパティへの比較的安価なバインディング更新で十分です。

DOMツリーを再作成すると、高いパフォーマンスペナルティに加えて、DOM要素のステート(例:フォーカス、テキストの選択、iframeでロードされたサイトなど)が失われます。

エラーの修正

アイテムのオブジェクトアイデンティティに関係なく、コレクション内のアイテムをユニークに識別するようにトラック式を変更します。説明した例では、正しいトラック式はユニークな id プロパティ(item.id)を使用します。

      
@Component({  template: `    <button (click)="toggleAllDone()">All done!</button>    <ul>    @for (todo of todos; track todo.id) {      <li>{{todo.task}}</li>    }    </ul>  `,})export class App {  todos = [    { id: 0, task: 'understand trackBy', done: false },    { id: 1, task: 'use proper tracking expression', done: false },  ];  toggleAllDone() {    this.todos = this.todos.map(todo => ({ ...todo, done: true }));  }}