NgRx 선택기 성능

10213 단어 angularperformancengrx
NgRx 선택기는 메모리를 통해 성능을 향상시킬 것을 약속합니다.그러나, 우리는 선택기를 정의할 때 반드시 조심해야 한다. 그렇지 않으면 우리는 기억에서 이익을 얻을 수 없을 것이다.사실상, 우리는 무의식중에 응용 프로그램의 성능을 떨어뜨릴 수 있다.

NgRx 선택기


NgRx 선택기에 익숙하지 않은 경우 Brandon Roberts on 또는 docs의 강연을 참조하십시오.그것들은 기본적으로 Store에서 데이터를 추출하는 방법이다.
다음은 이런 성능 함정에 빠지는 것이 얼마나 쉬운지 봅시다!

카운터 응용 프로그램


성능 함정을 보여주기 위해서 우리는 계수기 프로그램을 사용할 것이다.StackBlitz의 코드를 시도할 수 있습니다. 이것은 본문에 대한 보충입니다.
두 개의 카운터와 텍스트 상자가 있습니다.우리는 모든 계수기의 현재 값과 모든 계수기의 총계를 표시합니다.

우리 주에는 다음과 같은 인터페이스가 있다.
export interface CounterState {
  counter1: number;
  counter2: number;
  name: string;
}

export interface BusyState {
  //lots of updates happen here!
}

export interface RootState {
  counter : CounterState;
  busyState: BusyState;
}
주의, 우리는 두 가지 특징이 있는데, counterbusyState이다.말 그대로 busyState은 많은 업데이트를 받았다.

총수를 계산하다


스토리지에 파생 상태를 저장하고 싶지 않으므로 총 수를 동적으로 계산해야 합니다.템플릿에 표시할 총 수를 계산하는 몇 가지 방법이 있습니다.각각의 성능 특징이 있기 때문에 우리는 지금 이것에 대해 연구를 진행할 것이다.

Adding two numbers is a trivial operation but for the sake of this post let's imagine it is a very expensive computation which we must minimise calculating.


어셈블리의 총 계산


우리는 주입 저장소와 select 연산자를 사용하여 구성 요소의 총수를 직접 계산할 수 있다.
// Component
constructor(private store: Store<RootState>){}

this.total$ = store.pipe(select(state => 
                             state.counter.counter1 + state.counter.counter2)
                        );
그러나 이런 방법을 사용하면 계산은 우리 상태의 모든 변화에 대해 다시 실행될 것이다.이것은 BusyState에 대한 모든 변경 사항을 포함하며, 이러한 변경은 전혀 무관하며, 총수의 값을 영원히 바꾸지 않을 것입니다!이것은 우리의 행동에 정말 엉망이니 더 잘할 수 있는지 봅시다.

선택기를 사용하여 감속기의 총계를 계산하다


예상한 바와 같이, 우리는 선택기를 사용하여 성능을 향상시킬 것입니다.Tim Deschryver를 사용하여 @ngrx/store에 설명했습니다.이creator 함수를 사용하면 총 계산을 구성 요소에서 꺼내서 감속기에 넣을 수 있습니다.
// Reducer
import { createSelector, createFeatureSelector } from "@ngrx/store";

const featureSelector = createFeatureSelector<CounterState>("counter");

export const getTotal = createSelector(
  featureSelector, s => s.counter1 + s.counter2
);
우리는 특징 절편을 입력으로 하고 counter1 + counter2을 되돌려 전체적인 관찰 흐름을 얻는다.그리고 우리 구성 요소에서 그것을 사용해서 총수를 표시합니다.
// Component
this.total$ = store.pipe(select(getTotal));
이 선택기를 사용하는 것은 우리의 총 계산이 counter 특징 슬라이드의 변경에만 실행된다는 것을 의미한다.이것은 더 이상 BusyState의 무관한 변경으로 다시 운행하지 않기 때문에 매우 큰 개선이다.그러나 우리는 여기서 멈출 수 없다. 우리는 더 잘할 수 있다.

기억을 이해하다


이 점에서 중요한 것은 선택기의 기억이 어떻게 작동하는지 이해하는 것이다. 왜냐하면 우리는 여전히 그것을 충분히 이용하지 못했기 때문이다.
docs for selectors으로 돌아가겠습니다.

When using the createSelector and createFeatureSelector functions /store keeps track of the latest arguments in which your selector function was invoked. Because selectors are pure functions, the last result can be returned when the arguments match without re-invoking your selector function. This can provide performance benefits, particularly with selectors that perform expensive computation. This practice is known as memoization.


여기서 중요한 부분은 @ngrx/store이 최신 입력 파라미터를 추적하는 것이다.우리의 예에서 이것은 전체 counter의 특징 절편이다.
export const getTotal = createSelector(
  featureSelector, s => s.counter1 + s.counter2
);
왜 우리가 더 잘할 수 있는지 알아보기 위해서, 우리는 텍스트 입력을 통해 counter.name을 업데이트하기 시작합니다.매번 스피드에서 name을 업데이트하기 위해 동작을 조정합니다.매번 업데이트할 때, 우리는 총수를 다시 계산할 것이다. 왜냐하면 그것은 같은 특징 절단의 일부이기 때문이다.

조합 선택기를 사용하여 계산


문서에서 파악한 내용을 사용하면 getTotal 선택기를 다시 작성하여 자신의 매개 변수가 변경될 때만 실행할 수 있도록 합니다.우리는 getCounter1 선택기와 getCounter2 선택기를 조합하여 이 점을 실현한다.이 카운터 선택기는 특정 카운터가 업데이트될 때만 새 값을 보냅니다.이것은 반대로 getTotal 선택기의 매개 변수가 그 중 하나의 계수기의 값이 변경될 때만 변경된다는 것을 의미한다.
// Reducer
export const getCounter1 = createSelector(
  featureSelector, s => s.counter1
);

export const getCounter2 = createSelector(
  featureSelector, s => s.counter2
);

// Composed selector
export const getTotal = createSelector(
  getCounter1, getCounter2, (c1, c2) => c1 + c2
);
이 설정을 통해 counter.name으로 변경하면 총 수를 다시 계산하지 않습니다!우리는 마침내 기억을 충분히 이용했고, 절대적으로 필요할 때만 총계산을 실행할 수 있도록 확보했다.이것은 선택기 합성의 힘이다.

실제 생활 장면


비록 우리의 프레젠테이션 응용 프로그램은 너무 작아서 성능 문제가 없을 수 있지만, 이러한 원칙들은 대형 응용 프로그램에서 좋은 응용을 얻을 수 있다.
내가 개발한 응용 프로그램에서 우리는 서로 의존하는 하단 목록이 많다. 즉, 응용 프로그램의 선택을 업데이트하면 다른 응용 프로그램에서 사용할 수 있는 옵션을 필터할 수 있다.이것은 선택기에 의해 구동되며, 모든 선택기는 루트 저장소를 사용합니다.나의 임무는 이 선택자들의 둔함을 조사하는 것이다.내가 하는 첫 번째 일은 선택기를 실행할 때마다 로그아웃하는 것이다.수백 번이야!!
이것이 바로 내가 선택기 작성의 중요성을 발견했을 때다.위에서 말한 바와 같이, 이러한 변경을 진행한 후, 선택기 호출 수량은 수백 개에서 몇 개로 줄어들었다.성능이 현저히 향상되어 선택기가 더 이상 둔하지 않다.

마지막 생각


만약 선택기에서 계산 비용이 비교적 큰 동작을 실행한다면, 절대적으로 필요할 때만 이 코드를 실행할 수 있기를 바랍니다.조합 선택기는 이를 실현하고 응용 프로그램의 성능을 보호할 수 있는 기술이다.

좋은 웹페이지 즐겨찾기