TIL

2024.04.26 TIL #useSuspenseQuery #useSuspenseQueries #useMemo

inz1234 2024. 5. 17. 02:18

🚨  TroubleShotting

Why(이유) ?

팀프로젝트 중 코드리뷰 시간에

1. useQuery / useSuspenseQuery를 사용할 때 useMemo를 꼭 사용해야하나?

2. useSuspenseQuery를 사용하는 곳들이 많은데 useSuspenseQueries로 한번에 가져오면?

이라는 의문이 들어 팀원들과 회의를 했다.


1st How(과정) 

(1) useMemo는 언제 쓰이는지 부터 다시 생각해봤다.

useMemo는 "value"에 대한 memoization이다.

여기서의 value는  
1) 함수가 return하는 값 
2) 또는 값 자체
를 뜻한다. 

그럼 왜 memoization을 하나? 복잡한 연산이 re-렌더링 될 때마다 실행되는 것을 방지하기 위함이다.

(2) 즉, useQuery로 가져온 데이터를 useMemo로 감싸서,
그 데이터를 가지고 특정 연산으로 새롭게 return한 값을 memoization 한다는 것이다.

근데 만약 데이터를 업데이트 하는 빈도가 높다면?

 

(3) 결론은 데이터 업데이트 빈도가 높으면 useMemo를 사용하는 효과가 미미하다.

데이터가 전체가 변경되면 어차피 useMemo안에 있는 연산을 다시 실행해야하기 때문이다.

 

ㅇㅇㅇ: 의존성 배열에 추가해서 re-렌더링 되는 걸 막을 수는 없을까?

의존성 배열에 무언가를 추가한다고 한들, useMemo는 re-렌더링에 관여하지 않는다.

useMemo의 의존성 배열 안에 들어간 state가 외부에서 바뀌면
re-렌더링이 일어나는 것이 아니라, useMemo 안의 로직이 재실행 될 뿐이다.

전체 데이터가 변경되는 게 아니라는 전제 하에
데이터 중 부분적인 요소를 useMemo의 의존성 배열에 추가하는 것은 일정 성능개선에 도움이 될 수 있다. 
이거 중에 이것만 바뀌면 연산을 재실행 해줘~ 가 되니깐.

따라서, 데이터 업데이트 빈도가 낮을 경우에는 당연히 useMemo의 사용이 성능개선에 도움이 된다.


2nd How(과정) 

(1) useSuspenseQueries란? 
useSuspenseQuery 여러 개를 하나의 배열로 묶어서 요청을 보내는 것을 말한다.

장점
- 코드 간결화
- 병렬로 동시에 Query 실행, 로딩 속도 감소
- 하나의 객체로 결합해서 반환을 해주기 때문에 재사용성이 좋음

단점
- 모든 Query의 결과가 다 반환될 때 까지 기다렸다가 렌더링
 => 오래 걸리는 Query 하나가 있으면 그걸 기다리는 동안 다른 데이터들도 렌더링 되지 않기 때문에 TTV가 길어질 수 있음
- 의존적인 Query A, B가 있다면 어차피 순서가 필요하기 때문에 병렬 요청이 의미가 없음
- A, B 데이터를 useSuspenseQueries로 가져오고, A를 invalidate하면 useSuspenseQueries가 다시 실행되므로 B query도 불필요하게 다시 가져옴(= 불필요한 서버요청)

(2) 이러한 장/단점을 가지기 때문에
오래 걸리지 않는 Query들,
서로 의존적이지 않은 Query들,
invalidateQueries 빈도가 적은 Query들
에는 useSuspenseQueries가 적합하지만 반대의 경우에는 오히려 로딩 속도 저하를 초래할 수 있다는 결론이 나왔다.