여러 Angular 리소스 (아래 참조)를 읽을 때 템플릿에서 메서드를 호출하면 성능 문제가 발생할 수 있습니다. 예
<div>{{getDisplayName()}}</div>
그러나 Angular Material 라이브러리 예제 중 상당수가 템플릿에서 메서드를 호출합니다.
나무
https://material.angular.io/components/tree/examples
<mat-icon class="mat-icon-rtl-mirror">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
선택 테이블
https://material.angular.io/components/table/examples
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
[aria-label]="checkboxLabel(row)">
</mat-checkbox>
</td>
이러한 메서드는 Set에서 값을 반환합니다. 예 : https://github.com/angular/components/blob/4d4ee182de3f306c5fcf49853ef6ac71c4000eea/src/cdk/collections/selection.ts
isSelected(value: T): boolean {
return this._selection.has(value);
}
이러한 방법으로 인해 * 일반적인 방법처럼 성능 문제가 발생합니까? 아니면 내가 놓친 것이 있습니까?
자원
질문에 대한 궁극적 인 대답은 ' 예' 입니다. 이로 인해 성능 문제가 발생합니다. 다행스럽게도 실제로이를 극복하는 방법, 이유 및 방법을 쉽게 설명 할 수 있습니다.
설명을 위해 여러 매트 체크 박스를 복사하여 애플리케이션 어딘가에 삽입합니다.
그런 다음, checkboxLabel 메소드에서 맨 첫 번째 줄에 콘솔 로그를 넣으십시오. 페이지와의 상호 작용을 수행하고 상자 중 하나를 선택 및 선택 취소하는 것이 이상적입니다.
이제 콘솔을 확인하면 모든 mat-checkbox에 한 번씩 나타나는 checkboxLabel 콘솔 로그를 볼 수 있습니다. 따라서 3 개를 넣으면 3 번 볼 수있을 것 입니다.
그러나 이러한 지침을 정확히 따르면 테스트 페이지에 보관 한 내용과 프로젝트 설정에 따라 실제로 콘솔 로그가 여러 번 표시됩니다. 그리고 많은 사람들은 확실히 9 회 이상 을 의미 합니다.
어떻게 이런일이 일어 났습니까?
본질적으로 Angular가 작동하는 방식의 핵심은 DOM이 변경 될 때마다 이와 같은 메서드를 사용하는 모든 요소를 재평가해야합니다. 본질적으로 이전 값을 캐시하고 비교하지 않으므로 계산을 다시 수행하고 결과를 반환해야합니다.
따라서 displayName ()이 포함 된 div가 20 개인 경우 변경 사항이있을 때마다 많은 변경 사항이 발생합니다. 당연히 엄청난 성능 문제가 발생합니다. 대부분의 페이지에 표시되는 것보다 훨씬 더 많은 페이지가 있다고 생각하면 사람들이 코딩을 잘 못해서가 아니라 애플리케이션 성능을 유지하기 위해 고군분투하는 이유를 알 수 있습니다.
이것을 어떻게 극복 할 수 있습니까?
파이프.
대신이 방법을 계속 사용할 수있는 파이프로 변환하면이 캐싱 방법을 활용하여 전체 앱 성능을 높일 수 있습니다.
파이프는 다른 결과 만 반환하고 입력이 변경된 경우에만 함수를 호출합니다.
따라서 편의를 위해 다음과 같은 배열이있는 더미 ts 파일을 설정해 보겠습니다.
labelExamples = [
{ row: '1' },
{ row: '1' },
{ row: '3' }
]
그리고 다음 코드가있는 html 파일 :
<ng-container *ngFor="let l of labelExamples">
<div>{{checkboxLabel(l.row)}}</div>
</ng-container>
마지막으로 ts 파일로 돌아가서 checkboxLabel 함수가 다음과 같다고 말합시다.
checkboxLabel(row: string) {
switch (row) {
case '1':
console.log("hello");
return 'Row 1 Label';
default:
console.warn("hello from the other side");
return 'Any other row label'
}
}
(이를 사용하여 위에서 설명한 내용을 정확히 테스트 할 수 있습니다.)
이것을 실행하면 내가 설명한대로 콘솔 로그 "Hello"및 "Hello from the other side"의 많은 인스턴스를 볼 수 있습니다.
그러나 이것을 파이프로 변경하면 위의 내용을 다음과 같이 변환 할 수 있습니다.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'checkboxLabelPipe'
})
export class checkboxLabelPipe implements PipeTransform {
transform(row: string | string): string {
if (row) {
return this.checkboxLabel(row);
}
return row;
}
checkboxLabel(row: string): string {
switch(row) {
case '1':
console.log('Row 1 called');
return 'Row 1 Label';
default:
console.log('Any other row called');
return 'Any other row label'
}
}
}
이것이 파이프라는 것을 기억하십시오. 따라서 사용되는 NgModule 또는 전역 NgModule에서 선언되어야합니다.
대신 이것을 실행하고 동일한 html 파일과 동일한 labelExamples 배열을 유지하면 콘솔 로그를 살펴 보는 경우를 제외하고는 이전과 똑같은 결과를 볼 수 있습니다. . 3 개의 콘솔 로그.
Angular에서 계산이 수행되는시기와 방법을 정확히 이해하고 함수 나 파이프를 가장 잘 사용하는시기를 이해하면 전체 애플리케이션의 성능을 크게 높일 수 있습니다.
Angular Documentation에서 Pipes가이를 달성하는 방법에 대해 자세히 알아볼 수 있습니다. 앵귤러 파이프 문서
또한 더 큰 성능 향상을 위해 메모 데코레이터를 살펴볼 수 있습니다. 메모 데코레이터 npm은 여기에서 찾을 수 있습니다. 이미 계산 된 결과를 캐시하고 프로세스를 거치지 않고 저장 한 결과를 반환하여 더 많은 성능을 절약합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다