Angular - *ngIf 대 템플릿의 단순 함수 호출
이미 답변이 완료된 경우 죄송합니다. 특정 시나리오와 일치하는 내용을 찾을 수 없습니다. 시작합니다!
우리는 각진 템플릿의 함수 호출에 대해 개발팀에서 논의했습니다.일반적인 경험으로 볼 때, 우리는 여러분이 이것들을 해서는 안 된다는 것에 동의합니다.하지만, 우리는 언제가 괜찮은지 논의하려고 노력했습니다.제가 시나리오를 하나 드리겠습니다.
예를 들어 ngIf로 감싸여 다음과 같은 여러 매개 변수를 확인하는 템플릿 블록이 있다고 가정합니다.
<ng-template *ngIf="user && user.name && isAuthorized">
...
</ng-template>
다음과 같은 것과 비교하여 성능에 상당한 차이가 있습니까?
템플릿:
<ng-template *ngIf="userCheck()">
...
</ng-template>
유형 스크립트:
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized;
}
질문을 요약하자면, 마지막 옵션에 상당한 성능 비용이 발생합니까?
우리는 두 가지 이상의 조건을 확인해야 하는 상황에서 두 번째 접근법을 사용하는 것을 선호하지만, 온라인의 많은 기사들은 함수 호출이 항상 템플릿에서 나쁘다고 말하지만, 이 경우에 정말 문제가 있습니까?
저는 또한 템플릿의 함수 호출을 최대한 피하려고 노력했지만, 당신의 질문은 저에게 빠른 조사를 하도록 영감을 주었습니다.
는 캐싱을 더 추가했습니다.userCheck()
*ngIf="isUserChecked"
...
// .ts
isUserChecked = this.userCheck()
여기서 데모를 준비했습니다. https://stackblitz.com/edit/angular-9qgsm9
놀랍게도 사이에 차이가 없는 것처럼 보입니다.
*ngIf="user && user.name && isAuthorized"
그리고.
*ngIf="userCheck()"
...
// .ts
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized;
}
그리고.
*ngIf="isUserChecked"
...
// .ts
isUserChecked = this.userCheck()
이것은 단순한 재산 검사에 유효한 것처럼 보이지만, 만약 어떤 것에 관한 한 분명히 차이가 있을 것입니다.async
동작, 예를 들어 어떤 api를 기다리는 게터.
이것은 꽤 신중한 대답입니다.
이와 같은 기능의 사용은 완벽하게 허용됩니다.그러면 템플릿이 훨씬 명확해지고 오버헤드가 크게 발생하지 않습니다.JB가 전에 말했듯이, 그것은 또한 유닛 테스트를 위한 훨씬 더 나은 기반을 마련할 것입니다.
또한 템플릿에 포함된 표현식은 변경 감지 메커니즘에 의해 함수로 평가되므로 템플릿에 포함된 표현식이든 구성 요소 논리에 포함된 표현식이든 상관없다고 생각합니다.
함수 내부의 논리를 최소한으로 유지합니다.그러나 이러한 기능이 성능에 미치는 영향에 대해 경계한다면, 저는 당신에게 다음과 같은 기능을 사용할 것을 강력히 권고합니다.ChangeDetectionStrategy
로.OnPush
어쨌든 그것은 최선의 방법으로 여겨집니다.이것을 사용하면, 함수는 매 사이클마다 호출되지 않습니다. 오직 다음과 같은 경우에만Input
변경 사항, 일부 이벤트가 템플릿 내부에서 발생하는 등
(using etc, because I don't know the other reason anymore).
개인적으로 다시 말씀드리지만, 관찰 가능한 패턴을 사용하는 것이 훨씬 더 좋다고 생각합니다. 그러면 다음을 사용할 수 있습니다.async
파이프, 그리고 새 값이 방출될 때만 템플릿이 다시 생성됩니다.
userIsAuthorized$ = combineLatest([
this.user$,
this.isAuthorized$
]).pipe(
map(([ user, authorized ]) => !!user && !!user.name && authorized),
shareReplay({ refCount: true, bufferSize: 1 })
);
그런 다음 템플릿에서 다음과 같이 사용할 수 있습니다.
<ng-template *ngIf="userIsAuthorized$ | async">
...
</ng-template>
하지만 또 다른 옵션은 사용하는 것입니다.ngOnChanges
구성 요소에 대한 모든 종속 변수가 입력이고 특정 템플릿 변수를 계산하는 논리가 많은 경우(표시한 경우가 아님):
export class UserComponent implements ngOnChanges {
userIsAuthorized: boolean = false;
@Input()
user?: any;
@Input()
isAuthorized?: boolean;
ngOnChanges(changes: SimpleChanges): void {
if (changes.user || changes.isAuthorized) {
this.userIsAuthorized = this.userCheck();
}
}
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized || false;
}
}
템플릿에서 다음과 같이 사용할 수 있습니다.
<ng-template *ngIf="userIsAuthorized">
...
</ng-template>
여러 가지 이유로 권장되지 않습니다.
userCheck()를 다시 렌더링해야 하는지 여부를 결정하려면 Angular에서 userCheck() 식을 실행하여 반환 값이 변경되었는지 확인해야 합니다.
Angular는 userCheck()의 반환 값이 변경되었는지 여부를 예측할 수 없으므로 변경 감지가 실행될 때마다 함수를 실행해야 합니다.
따라서 변경 감지가 300회 실행되면 반환 값이 변경되지 않더라도 함수를 300회 호출합니다.
확장 설명 및 기타 문제 https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496
구성 요소가 크고 많은 변경 이벤트에 참석할 때 발생하는 문제는 구성 요소가 적고 몇 가지 이벤트에만 참석할 경우 문제가 되지 않습니다.
관측치가 있는 예제
user$;
isAuth$
userCheck$;
userCheck$ = user$.pipe(
switchMap((user) => {
return forkJoin([of(user), isAuth$]);
}
)
.map(([user, isAuthenticated])=>{
if(user && user.name && isAuthenticated){
return true;
} else {
return false;
}
})
);
그러면 당신은 당신의 코드에 있는 비동기 파이프와 함께 관찰 가능한 것을 사용할 수 있습니다.
자바스크립트는 개발자가 표현식과 함수 호출의 차이를 눈치채지 못하도록 목표를 가지고 만들어졌다고 생각합니다.
C++에는 키워드가 있습니다.inline
함수를 표시합니다.예:
inline bool userCheck()
{
return isAuthorized;
}
이것은 함수 호출을 제거하기 위해 수행되었습니다.결과적으로 컴파일러는 다음의 모든 호출을 대체합니다.userCheck
함수의 본문과 함께.혁신의 이유inline
성능 향상.
따라서 하나의 식을 가진 함수 호출의 실행 시간은 식만 실행하는 것보다 느릴 것이라고 생각합니다.그러나 기능에 하나의 표현만 있으면 성능의 차이를 눈치채지 못할 것이라고 생각합니다.
언급URL : https://stackoverflow.com/questions/59784856/angular-ngif-vs-simple-function-calls-in-template
'code' 카테고리의 다른 글
iPhone의 장치 이름을 가져오는 방법 (0) | 2023.07.07 |
---|---|
jQuery로 머리글과 바닥글 사이를 스크롤할 때 사이드바를 고정시키는 방법은 무엇입니까? (0) | 2023.07.02 |
TypeScript의 클래스에 오리 타이핑이 허용되는 이유 (0) | 2023.07.02 |
숨겨진 셀 찾기 수행 (0) | 2023.07.02 |
gitsvn을 사용하여 원격 지점 체크아웃 (0) | 2023.07.02 |