각도 구성 요소 템플릿에서 간단한 메서드를 호출하면 성능 문제가 발생할 수 있습니까?

7R1X

여러 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);
}

이러한 방법으로 인해 * 일반적인 방법처럼 성능 문제가 발생합니까? 아니면 내가 놓친 것이 있습니까?

자원

템플릿에서 함수를 호출하면 Angular2 +에서 성능 문제가 발생합니까?

https://blog.mgechev.com/2017/11/11/faster-angular-applications-onpush-change-detection-immutable-part-1/

cm 프로그램

질문에 대한 궁극적 인 대답은 ' 예' 입니다. 이로 인해 성능 문제가 발생합니다. 다행스럽게도 실제로이를 극복하는 방법, 이유 및 방법을 쉽게 설명 할 수 있습니다.

설명을 위해 여러 매트 체크 박스를 복사하여 애플리케이션 어딘가에 삽입합니다.

그런 다음, 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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관