이 외에도 이것저것 많이 들어갔는데 돌이켜보니 너무 힘들었다...
이번에 제작하게 된 개인과제에서는 데이터를 조회하여 카드형태로 나타내기만 하면 어떻게 보면 가벼운 과제라고 생각했으나 그 내부에서 이것저것 추가하다보니 여러모로 너.... 무 고생하고 힘들었던 순간이 많았다.
특히 그 과정 중에서 스트레스를 유발하던 것들이 몇개 있었는데 이것들을 나열해보고자 한다.
이제까지 브라우저 저장공간이 localstorage, cookie storage 정도라고 생각했던 나에게 cache stotrage는 몹시도 생소하고 흥미로운 장소였다.
이번 요구사항 내용 중에서 초기 요청이 일어난 이후에는 캐시 형태로 내용을 저장해서 거기에서 조회해달라는 요구사항이 존재했어서 이것을 구현하기 위해 이것저것 찾아본게 많았다.
<round 1. 아 리퀘스트 캐싱하라는 의미인걸까?>
처음엔 정말 단순하게 생각했다. 그냥 리퀘스트 내용을 캐싱해서 계속 그것을 사용하면 된다고 말이다.
그런데, 예기치 못한 조건이 더 있었다.
"새로고침을 하게 되면 다시 요청을 보내지 않고 캐싱했던 내용을 사용해서 데이터를 조회하고..."
캐싱이라는 소리를 보자마자 바로 React-Query를 사용해서 구현해야지 하고 생각했던 나에게는 청천벽력과 같은 내용이었다.
왜냐하면 React-Query의 캐싱은 새로고침을 하면 유지가 되지 않기 때문이다.
(다시말하면, 새로고침을 해도 브라우저에 데이터가 저장되어있어야 한다)
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Home />
</QueryClientProvider>
);
} // 리엑트 쿼리는 기본적으로 앱이 실행되는 순간 ContextAPI 처럼 props를 자식들에게 보내주는 구조로 되어있다. 그리고 요청의 캐싱내용도 마찬가지로 provider인 queryClient에 저장되었다가 새로고침하면 휘발되는 구조기 때문에 맞지 않다.
다른 의미로 axios의 캐싱도 만지작거려봤지만 동일한 결과를 낳았다.
위 이미지처럼 axios의 인스턴스를 생성하면서 옵션으로 adapter을 전하며 기본 캐싱행위를 저지시키고 헤더로도 명시적으로 no-cache를 해둔 후,
내가 필요할 때 ajax 요청을 하는 대상에 선택적으로 캐싱하게 만들어두면 재요청을 하지 않고 캐싱내용을 전달한다.
위처럼 요청은 계속 가지만,
네트워크 요청은 한번만 하는 것을 알 수 있다.
만약 react-query를 사용하지 않고 axios만으로 캐싱을 반영하고 싶다면 해당 방식이 좋은 솔루션이 될 것 같다고 배운 경험이 되었다.
뭐... 그치만 지금 그게 중요한게 아니고 새로고침에 캐싱이 되어야하는게 더 중요하니
<round 2. 그럼 로컬스토리지로?>
새로고침에 대해서 방지책을 생각해보라면 가장 먼저 떠오르는 것이 localstorage일 것이다. 그런데 로컬 스토리지는 사실 데이터를 캐싱하기에는 조금 부담스러운 부분이 존재한다.
그것은 바로 용량 공간이 생각보다 많지 않다는 것!
api요청을 한번 해보니 데이터가 수천개가 날아오는 것을 보며 나중에라도 데이터 내용이 확장한다면 이것을 죄다 localstorage에 저장하면서 사용하기엔 무리가 있다 라는 판단을 하게되었다.
그래서 이것저것 찾아보니
위 스크린샷은 Google 엔지니어 성님의 홈페이지 답변 내용이다. 생각보다 localstroage에 대해서 몹시 부정적인 의견을 내고 있다는 것에 한번 놀랐고,
생전 처음듣는 cache storage와 indexed DB라는 것을 추천하여 네트워크 요청 정보를 저장하라고 하는 것을 알 수 있다. 그렇다면 이렇게 추천을 하는 이유가 따로 있을것이다.
아니 어머나 세상에 localstorage는 5mb 문자열밖에 못하면서 애는 디스크 최대 60%까지 저장이 가능하다고? 수G까지도 저장이 될 수 있다고?
사용하지 않을 이유가 없구만
하는 생각으로 사용했다가 정말 많은 피를 보게 되어 여기에 남긴다.
<round 3. 캐시 스토리지를 사용해보자>
위의 이미지에서 볼 수 있듯, cache storage를 사용하는 방법은 생각보다 간단하다.
특정 url을 설정해두고 caches윈도우의 객체 프로퍼티 내부에 있는 메서드 open을 호출하면 된다. 그리고나서 조건부로 데이터가 존재할때, 그리고 존재하지 않을 때를 나누어서 로직을 처리하면 된다.
다만, 이때 좀 특이한점은 요청정보가 없어서 else로 fetching하여 response 객체를 캐싱하는 경우인데, 이 객체를 한번 캐싱하면 그 뒤에 json()을 통해 data 값을 호출하는 것이 불가능하므로 (무슨 원리인지는 모르겠지만 신기했다) 반드시 put으로 집어넣기 전에 미리 clone 메서드를 호출해야 함을 명심해야 한다.
그리고 또 중요한것이 위의 이미지를 보면 fetch를 사용하는 것을 볼 수 있는데, 만약 이렇게 비동기적인 작업을 try 블록에 집어넣을 경우 에러가 발생하면 잡아내지 않기 때문에 반드시 catch를 이용하여 따로 처리해야 한다.
이와 관련된 내용은 기존 에러로그에 조금 더 자세하게 기술해놓았다.
비동기 에러 처리와 관련하여 주의점!
캐시 스토리지의 데이터내용은 위와같이 어플리케이션의 저장공간에서 확인이 가능하다. 다만, 이 스토리지 내용만 조회해서는 데이터를 전달해주지 않아서 반드시 json 메서드로 변환 호출해서 가져와야 한다.
고민한 부분이 완젼히 똑같네요 ㅠㅠ axios로 쓰려고 하는데 계속 에러를 뱉고 ㅠㅠ 데이터 전달이 안되서 애먹었는데 json() 꿀팁 알아갑니다 ~!!!!