두 라이브러리를 비교할 때, 흔히 경량화나 기능성 관점에서 다루는 글이 많았다. 하지만 이 차이는 실제 체감되는 부분이 적게 느껴졌다.
Module Federation 환경에서 두 라이브러리 중 어느것을 선택해야하는지에 대한 궁금증이 생겨서 실험해보았다
막상 사용해보니 캐싱을 효과적으로 모두 캐싱을 제대로 처리하지 못하는 문제를 발견했고, 이 문제를 해결하면서 더 나은 라이브러리를 선택하고자했다.
결론은, SWR이 더 나은 선택지였다.
SWR은 서로 다른 서비스 간에 캐시 키 값을 훨씬 쉽게 공유할 수 있기 때문이었다.
React-Query에서 여러 방법을 실험해본 결과, 캐시 상태를 제대로 공유하지 못하는 문제가 지속적으로 발생했습니다. 아래는 시도해본 방법들입니다:
QueryClientProvider
지정 → ❌useQueryClient()
로 받은 값을 다른 서비스에 props로 전달 → ❌client
객체를 전역 객체에 저장해서 공유 → ❌QueryClientProvider
의 contextSharing
사용 → v4부터 deprecated, v5에서는 제거 → ❌SWR의 경우, SWRConfig와 Module Federation의 eager/singleton 옵션을 추가한 방법이 성공적으로 캐싱 상태를 공유할 수 있었습니다.
이 차이는 두 라이브러리의 캐싱 구현 방식에서 비롯된 것입니다.
useSWR
훅을 바로 사용할 수 있습니다.Module Federation은 서로 다른 서비스에서 같은 패키지를 사용하더라도, 기본적으로 격리된 환경을 제공하므로 캐싱 상태를 공유하지 못하게 만듭니다. 그러나 singleton 옵션을 활성화하면 특정 패키지를 ‘같은 소스 코드’로 간주하게 만들 수 있습니다. SWR은 전역 객체를 사용하기 때문에, 이 옵션을 통해 같은 캐싱 상태를 공유할 수 있었습니다.
반면, React-Query는 각각의 서비스에서 QueryClientProvider로 감싸줘야 하며, 이 과정에서 서로 다른 context로 인식하게 되어 캐싱을 공유하지 못했습니다.
React-Query 역시 singleton 옵션을 활성화하고, 상위 서비스에서만 QueryClientProvider
를 사용할 수 있습니다. 그러나 React-Query는 QueryClientProvider
가 없을 경우 에러를 발생시키며, React Context Provider가 없다고 판단합니다. 이를 해결하기 위해 v4에서는 contextSharing
옵션을 제공했으나, 이 기능은 v4부터 deprecated 상태이고 v5에서 완전히 제거되었습니다.
SWR은 Module Federation 환경에서 전역 객체를 활용해 캐싱 상태를 공유할 수 있는 점에서 더 나은 선택지였습니다. React-Query는 캐싱 문제를 해결하기 위해 deprecated 기능을 사용하거나 비효율적인 방법을 요구하기 때문에, 현실적으로 SWR을 사용하는 것이 더 적합하다고 판단했습니다.