0303 로컬캐싱 구현

냐하호후·2022년 3월 3일
3

캐싱

캐싱(Caching)은 애플리케이션의 처리 속도를 높여준다. 이미 가져온 데이터나 계산된 결과값의 복사본을 저장함으로써 처리 속도를 향상시키며, 이를 통해 향후 요청을 더 빠르게 처리할 수 있다. 대부분의 프로그램이 동일한 데이터나 명령어에 반복해서 엑세스하기 때문에 캐싱은 효율적인 아키텍처 패턴이다.

캐시의 장점

애플리케이션 성능 개선
데이터베이스 비용 절감
백엔드 부하 감소
예측 가능한 성능

처음엔 React Query를 이용해서 로컬캐싱을 구현하다가 React Query보다 최근에 나온 RTK Query를 쓰는게 어떻냐는 팀원분의 제안을 받아들였다.

keepUnusedDataFor만 집어 넣으면 expire 시간을 설정할 수 있다.

그래서 라이브러리의 사용 없이 직접 구현도 해보기로 했다.

로컬스토리지에 데이터 저장, 불러오기

localStorage.getItemlocalStorage.setItem 메서드를 이용해서 로컬 스토리지에 받아온 데이터를 저장할 수 있었다.

로컬스토리지에서는 데이터를 저장할 때 JSON형식으로 저장하기 때문에, getItem으로 로컬스토리지에서 데이터를 받아와 state에 넣어둘 땐 JSON.parse 메서드를 이용해서 저장해야한다.
새로 데이터를 로컬 스토리지에 저장할 때는 JSON.stringify메서드를 사용해서 저장했다.

로컬스토리지에서 불러온 데이터 store에 저장하기

const ONE_MINUTE = 1000 * 60;

export const searchResultRequest = createAsyncThunk(
  "request",
  async (searchInput) => {
    const checkCache = localStorage.getItem(searchInput);

    if (checkCache) {
      return checkCache;
    } else {
      const response = await api.get(searchInput);
      const object = {
        data: response.data,
        expireTime: new Date().getTime() + ONE_MINUTE,
      };
      localStorage.setItem(searchInput, JSON.stringify(object));

      return JSON.stringify(object);
    }
  }
);

export const resultSlice = createSlice({
  name: "result",
  initialState: { data: [] },
  reducers: {},
  extraReducers: {
    [searchResultRequest.fulfilled]: (state, { payload }) => {
      state.data = JSON.parse(payload).data;
    },
  },
});

extraReducer는 slice.actions에서 생성되지 않은 action을 사용할 수 있게 해준다.
주로 다른 slice에 정의된 action이나 createAsyncThunk에서 사용된 비동기 action을 설정할 때 사용한다.

expiry time 설정하기

localStorage.removeItem 또는 localStorage.clear를 이용해서 값을 제거할 수 있다.

 useEffect(() => {
    // 만료시간 지난 캐시 삭제
    for (let elem in localStorage) {
      const localStorageElem = JSON.parse(localStorage.getItem(elem));
      if (
        localStorageElem?.expireTime &&
        localStorageElem?.expireTime <= Date.now()
      ) {
        localStorage.removeItem(elem);
      }
    }
  }, []);

로컬스토리지에 있는 데이터들을 전체 다 보았을 때 expireTime(처음API호출했던 시간 + 1분)이 현재시간과 같아지면 로컬 스토리지에 저장된 데이터를 삭제한다.

느낀 점

나중에 알게 되었는데 로컬캐싱의 정석적인 방법은 in-memory로 저장하는 것이라고 한다.
다음엔 indexDB를 이용해서 로컬캐싱을 구현해보아야 겠다.

profile
DONE is better than PERFECT

0개의 댓글