이번에는 Angular 코드를 최적화하는 방법과 Angular 코드를 최적화할 때 주의 사항이 무엇인지 알려드리겠습니다. 아래에서 실제 사례를 살펴보겠습니다.
Summary
Angular 4의 더티 값 감지는 오래된 주제이며, 이 모델을 이해하는 것이 Angular 성능 최적화의 기초입니다. 따라서 오늘은 Angular 4의 더티 값 감지 원리에 대해 이야기하고 성능 최적화를 위한 몇 가지 팁을 살펴보겠습니다.
Entry Point - Zone.js
Angular 4는 MVVM 프레임워크입니다. 데이터 모델(Model)이 뷰 모델(ViewModel)로 변환된 후 뷰(View)에 바인딩되어 육안으로 볼 수 있는 페이지로 렌더링됩니다. 따라서 데이터 모델이 변경되는 시점을 발견하는 것이 페이지 업데이트 및 더티 값 감지 호출의 핵심입니다.
분석 후 엔지니어들은 데이터 변경이 매크로태스크 및 마이크로태스크와 같은 비동기 이벤트로 인해 발생하는 경우가 많다는 사실을 발견했습니다. 따라서 브라우저에서 모든 비동기 API를 다시 작성하면 소스에서 데이터 변경 사항을 효과적으로 모니터링할 수 있습니다. Zone.js는 그런 원숭이 스크립트(Monkey Patch)입니다. Angular 4는 사용자 정의된 영역(NgZone)을 사용하여 데이터 변경이 있을 수 있으며 뷰의 데이터를 업데이트해야 함(더티 값 감지)을 Angular에 알립니다.
더티 값 감지(Change 감지)
더티 값 감지의 기본 원리는 이전 값을 저장하고 감지 시 현재 순간의 새 값과 이전 값을 비교하는 것입니다. 동일하면 변경 사항이 없습니다. 그렇지 않으면 변경 사항이 감지되어 뷰를 업데이트해야 합니다.
Angular 4는 페이지를 여러 구성 요소로 나누어 구성 요소 트리를 형성합니다. 더티 값 감지를 입력한 후 루트 구성 요소부터 위에서 아래로 감지가 수행됩니다. Angular에는 Default와 OnPush라는 두 가지 전략이 있습니다. 이는 구성 요소에 구성되며 더티 값 감지 중에 다양한 동작을 결정합니다.
Default - 기본 전략
ChangeDetectionStrategy.Default. 이는 또한 데이터를 변경할 수 있는 이벤트가 발생하면 이 구성 요소가 항상 테스트된다는 것을 의미합니다.
더티 값 감지 작업은 기본적으로 다음 단계로 이해될 수 있습니다. 1) 하위 구성 요소에 바인딩된 속성을 업데이트합니다. 2) 하위 구성 요소의 NgDoCheck 및 NgOnChanges 수명 주기 후크를 호출합니다. 3) 자체 DOM을 업데이트합니다. 4) 하위 구성 요소의 더티 값을 감지합니다. 이는 루트 구성 요소에서 시작하는 재귀 방정식입니다.
// This is not Angular code function changeDetection(component) { updateProperties(component.children); component.children.forEach(child => { child.NgDoCheck(); child.NgOnChanges(); }; updateDom(component); component.children.forEach(child => changeDetection(child)); }
우리 개발자들은 DOM 업데이트 순서와 NgDoCheck 및 NgOnChanges 호출 순서에 큰 주의를 기울일 것입니다.
DOM 업데이트는 깊이 우선입니다.
NgDoCheck 및 NgOnChanges는 깊이 우선이 아닙니다.
OnPush - 단일 탐지 전략
ChangeDetectionStrategy.OnPush. 이 구성 요소는 입력 속성이 변경되는 경우(OnPush)에만 감지됩니다. 따라서 입력이 변경되지 않는 경우 초기화 중에만 감지되며, 이를 단일 감지라고도 합니다. 다른 동작은 기본값과 일치합니다.
OnPush는 입력에 대한 참조만 감지한다는 점에 유의해야 합니다. 입력 개체의 속성 변경은 현재 구성 요소의 더티 값 감지를 트리거하지 않습니다.
OnPush 전략은 성능을 향상시키기는 하지만 버그가 많이 발생하는 곳이기도 합니다. 해결책은 종종 입력을 불변 형식으로 변환하고 입력 참조를 강제로 변경하는 것입니다.
Tips
Data Binding
Angular에는 3가지 합법적인 데이터 바인딩 방법이 있지만 성능은 다릅니다.
데이터 직접 바인딩
<ul> <li *ngFor="let item of arr"> <span>Name {{item.name}}</span> <span>Classes {{item.classes}}</span><!-- Binding a data directly. --> </li> </ul>
대부분의 경우 이것이 가장 좋은 수행 방법입니다.
함수 호출 결과 바인딩
<ul> <li *ngFor="let item of arr"> <span>Name {{item.name}}</span> <span>Classes {{classes(item)}}</span><!-- Binding an attribute to a method. The classes would be called in every change detection cycle --> </li> </ul>
각 더티 값 감지 프로세스에서는 클래스 방정식을 한 번 호출해야 합니다. 사용자가 페이지를 스크롤하고 있고 여러 매크로태스크가 생성되었으며 각 매크로태스크가 최소한 한 번의 더티 값 확인을 수행한다고 가정해 보세요. 특별한 요구사항이 없다면 이 사용 방법은 최대한 피해야 합니다.
Bind data+pipe
<ul> <li *ngFor="let item of instructorList"> <span>Name {{item.name}}</span> <span>Classes {{item | classPipe}}</span><!-- Binding data with a pipe --> </li> </ul>
Dirty 값 감지 클래스Pipe가 호출될 때마다 바인딩 기능과 유사합니다. 그러나 Angular는 파이프를 최적화하고 캐싱을 추가했습니다. 항목이 마지막 시간과 같으면 결과가 직접 반환됩니다.
NgFor
대부분의 경우 NgFor는 trackBy 방정식과 함께 사용해야 합니다. 그렇지 않으면 NgFor는 각 더티 값 감지 프로세스 중에 목록의 각 항목에 대한 DOM을 업데이트합니다.
@Component({ selector: 'my-app', template: ` <ul> <li *ngFor="let item of collection;trackBy: trackByFn">{{item.id}}</li> </ul> <button (click)="getItems()">Refresh items</button> `, }) export class App { collection; constructor() { this.collection = [{id: 1}, {id: 2}, {id: 3}]; } getItems() { this.collection = this.getItemsFromServer(); } getItemsFromServer() { return [{id: 1}, {id: 2}, {id: 3}, {id: 4}]; } trackByFn(index, item) { return index; } }
이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!
추천 도서:
위 내용은 Angular 코드를 최적화하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!