고성능 Angular 애플리케이션을 위한 모범 사례 - #1부

4155 단어
이 기사에서는 성능이 높고 깔끔한 코드 기반을 갖기 위해 Angular 애플리케이션에서 일반적으로 사용해야 하는 방법을 간략히 설명합니다.
이 일련의 기사에서는 한 번에 하나의 연습을 게시할 것입니다.
이 시리즈 기사의 범위는 Angular, Typescript, RxJ 및
/가게.

오늘은 Observable에 대해 알아보겠습니다. 코딩 측면에서 Observable을 이해하고 사용하는 방법은 매우 중요합니다. 올바르게 사용하면 앱의 전체 성능에 미치는 피해를 줄이고 런타임에 많은 메모리와 CPU 사용량을 절약할 수 있습니다.
몇 가지 모범 사례가 아래에 언급되어 있으며, 이는 전혀 복잡하지 않으며 좋은 습관이나 나쁜 습관을 기르는 것과 같으며 일상 활동에 자동으로 반영됩니다.

1. 템플릿에서 구독



컴포넌트에서 옵저버블을 구독하는 것을 피하고 대신 템플릿에서 옵저버블을 구독하십시오.

왜 중요합니까?

비동기 파이프는 자동으로 구독을 취소하고 구독을 수동으로 관리할 필요가 없어 코드를 더 간단하게 만듭니다. 또한 구성 요소에서 구독 취소를 실수로 잊어버려 메모리 누수가 발생할 위험도 줄어듭니다. 이 위험은 구독되지 않은 관찰 가능 항목을 감지하는 린트 규칙을 사용하여 완화할 수도 있습니다.
또한 구성 요소가 상태 저장이 되지 않고 구독 외부에서 데이터가 변경되는 버그가 발생하지 않습니다.

전에

// template
<p>{{ textToDisplay }}</p>
// component
meTheObservable
    .pipe(
       map(value => value.item),
       takeUntil(this._destroyed$)
     )
    .subscribe(item => this.textToDisplay = item);


후에

// template
<p>{{ textToDisplay$ | async }}</p>
// component
this.textToDisplay$ = meTheObservable
    .pipe(
       map(value => value.item)
     );


2. 구독 정리



Observable을 구독할 때 항상 take, takeUntil 등과 같은 연산자를 사용하여 적절하게 구독을 취소해야 합니다.

왜 중요합니까?

옵저버블 구독 취소에 실패하면 옵저버블 스트림이 열려 있기 때문에 원치 않는 메모리 누수가 발생할 수 있습니다. 구성 요소가 파괴되거나 사용자가 다른 페이지로 이동한 후에도 잠재적으로 그렇습니다.
더 나은 방법은 구독 취소되지 않은 관찰 가능 항목을 감지하기 위한 린트 규칙을 만드는 것입니다.

전에

meTheObservable
    .pipe(
       map(value => value.item)     
     )
    .subscribe(item => this.textToDisplay = item);


후에

다른 옵저버블이 값을 방출할 때까지 변경 사항을 듣고 싶을 때 takeUntil 사용:

private _destroyed$ = new Subject();
public ngOnInit (): void {
    meTheObservable
    .pipe(
       map(value => value.item)
      // We want to listen to meTheObservable until the component is destroyed,

       takeUntil(this._destroyed$)
     )
    .subscribe(item => this.textToDisplay = item);
}
public ngOnDestroy (): void {
    this._destroyed$.next();
    this._destroyed$.complete();
}



이와 같은 비공개 주제를 사용하는 것은 구성 요소에서 많은 관찰 가능 항목을 구독 취소하는 것을 관리하는 패턴입니다.

Observable이 내보낸 첫 번째 값만 원할 때 take 사용:

meTheObservable
    .pipe(
       map(value => value.item),
       take(1),
       takeUntil(this._destroyed$)
    )
    .subscribe(item => this.textToDisplay = item);



메모:
여기에서 takeUntil의 사용법. 이는 구성 요소가 파괴되기 전에 구독이 값을 받지 못했을 때 발생하는 메모리 누수를 방지하기 위한 것입니다. 여기에 takeUntil이 없으면 구독은 첫 번째 값을 얻을 때까지 계속 매달려 있지만 구성 요소가 이미 파괴되었기 때문에 값을 얻지 못하여 메모리 누수가 발생합니다.

3. 구독 안에 구독을 두지 마십시오.



때로는 작업을 수행하기 위해 둘 이상의 관찰 가능한 값을 원할 수 있습니다. 이 경우 다른 Observable의 subscribe 블록에 있는 하나의 Observable에 대한 구독을 피하십시오. 대신 적절한 연결 연산자를 사용하십시오. 연결 연산자는 그 앞에 있는 연산자의 옵저버블에서 실행됩니다. 일부 연결 연산자는 withLatestFrom, CombineLatest 등입니다.

전에

firstObservable$.pipe(
   take(1)
)
.subscribe(firstValue => {
    secondObservable$.pipe(
        take(1)
    )
    .subscribe(secondValue => {
        console.log(`Combined values are: ${firstValue} & ${secondValue}`);
    });
});



후에

firstObservable$.pipe(
    withLatestFrom(secondObservable$),
    first()
)
.subscribe(([firstValue, secondValue]) => {
    console.log(`Combined values are: ${firstValue} & ${secondValue}`);
});



왜 중요합니까?

코드 느낌/가독성/복잡성: RxJ를 최대한 사용하지 않는 것은 개발자가 RxJ API 노출 영역에 익숙하지 않음을 시사합니다.

성능: 옵저버블이 콜드이면 firstObservable을 구독하고 완료될 때까지 기다린 다음 두 번째 옵저버블의 작업을 시작합니다. 이것이 네트워크 요청인 경우 동기로 표시됩니다.

결론



애플리케이션 개발은 가보지 않은 여정이며 항상 배우고 개선할 여지가 있습니다. 위에서 언급한 최적화 기술은 시작하기에 좋은 위치이며 이러한 패턴을 일관되게 적용하면 버그가 적고 성능이 좋은 응용 프로그램으로 귀하와 사용자를 만족시킬 수 있습니다.
다음 파트에서 나는 다른 주제를 가지고 그것에 대해 토론할 것입니다.

좋은 웹페이지 즐겨찾기