
기술 면접 구독 서비스, 매일메일이란 서비스를 알게 되고, 면접 질문 메일링을 받은 지 어느덧 4일이 지났다.
tanstack-query에서stale time과gc time의 차이점에 대해서 설명해주세요
라는 질문이 들어왔고,
요즘 나름 관심있게 뜯어보던 tanstack-query의 캐싱 전략에 관련된 질문이라 답변을 정리 겸 기록하고자 글을 작성하게 되었다.
우선 처음 끄적여보던 답변은 이와 같다.
👩🏻 staleTime은 캐시 데이터가 신선할 수 있는 즉, 메모리에 저장되는 시점까지의 시간을 의미하고, gcTime은 캐시 데이터가 메모리에서 제거되기 까지의 시간을 의미한다.
라고 끄적였고, 이에 대한 평가를 chatGPT한테 부탁했다.
🤖 너가 정리한 답변도 아주 좋아! 다만, 용어 선택을 조금만 더 명확하게 하고, 질문 의도에 맞게 차이점에 포커스를 맞춰 설명하면 면접에서도 더 설득력 있게 전달할 수 있어.
그러자 이렇게 답변이 왔고, 답변의 예시까지 함께 보여주었다.
staleTime은 데이터를 '신선한 상태(fresh)'로 간주할 수 있는 시간을 의미합니다. 이 시간 동안은 쿼리가 다시 요청되어도 네트워크 요청을 하지 않고, 캐시된 데이터를 그대로 사용합니다.
반면gcTime은 쿼리가 사용되지 않는 상태(inactive)가 된 이후, 해당 쿼리 데이터를 메모리에서 완전히 제거할 때까지의 유예 시간입니다.
사실 gcTime은 사용해보지 않아서 감이 잘 오지 않았었는데, 해당 답변을 통해 "사용되지 않는 상태 이후의 전략"에 대해서는 깊게 생각해보지 않았다는 사실을 깨달을 수 있었다.
더불어 정확한 gcTime의 개념까지 파고들기에 적절했다.
staleTime은 데이터가 신선한 시간을 설정하고, 설정한 시간이 지나면 refetch() 혹은 invalidateQueries()과 같은 전략을 통해 데이터를 다시 가져와야 하는 대상이 된다.
이후 데이터를 새롭게 가져오면서 발생된 이전 데이터는 메모리에 담기게 되는데, 이 메모리에 담겨있는 시간을 설정하는 것이 바로 gcTime인 것이다.
즉, staleTime은 "데이터를 다시 가져올 수 있는 대상"이 되는 시점을 설정하는 시간을 의미하고, gcTime은 그로 인해 발생한 이전 데이터가 제거되는 시점을 설정하는 시간을 의미한다.
번외로, gcTime은 Infinity로 설정할 수도, 0으로 설정할 수도 있어서 절대 제거되지 않게 하거나 혹은 컴포넌트가 언마운트 되면 바로 제거되게 할 수도 있다고 한다.
gcTime을 통해 데이터를 다시 요청할 비용이 비싼 경우는 gcTime을 늘려 캐시를 유지하는 방식으로, 혹은 gcTime을 줄여서 빠르게 제거하여 메모리를 절약하는 방식으로도 사용이 가능하다.
다음 나올 내용은, 이와 같이 개념을 정리하면서 물었던 꼬리들이다.
기본값은 5분이다.
즉, 5분 동안 사용되지 않은 쿼리는 메모리에서 자동으로 제거된다.
"사용 중"의 기준은 해당 쿼리를 구독하는 컴포넌트가 존재하는가이며, "사용되지 않은"은 이의 반대다.
Tanstack Query는 내부적으로 query observer라는 걸 통해, 해당 쿼리를 구독 중인 컴포넌트의 존재 여부를 추적한다.
const { data } = useQuery({ queryKey: ["user"], queryFn: fetchUser });
예를 들어, 이와 같이 useQuery가 실행되면 해당 컴포넌트를 observer로 등록하고, 언마운트 될 경우 자동으로 구독을 해제한다.
그래서 내부적으로 해당 observer가 0명일 때를 감지해서
// 내부 로직과 다를 수 있으며, 이해를 돕기 위한 예시 코드입니다.
setTimeout(() => {
if (observers.length === 0) deleteQueryFromCache();
}, gcTime)
이와 같은 흐름으로 메모리에서 삭제까지 이루어지게 되며, 눈에 보이지 않지만 해당 과정이 이루어진다.
이처럼 Tanstack Query는 의도적으로 메모리 누수 방지를 고려하여 설계되었기 때문에, 위와 같은 내부 과정이 이루어지고 메모리 관리에 효율적이다.
이제 함께 보내주신 답안을 읽으며 마무리하러..
Thanks to 매일메일 😍