쇼핑몰 페이지 최적화하기 2 [localStorage]

자몽·2021년 8월 25일
1

Toy-Project

목록 보기
8/13
post-thumbnail

쇼핑몰 프로젝트 깃허브 링크:

https://github.com/OseungKwon/Shopping-mall

문제점

이미 방문했었던 제품 페이지라도 서버에서 같은 데이터를 계속 가져와 로딩 속도가 느렸다.

이를 해결하기 위한 방법으로써 localStorage를 생각해냈다.
쇼핑몰 페이지의 유저 데이터를 localStorage에 저장시켜놔서 새로고침을 해도 유저의 데이터가 날라가지 않게 했다는 점에서 아이디어를 얻었다.

[개선 1] 각 프로퍼티를 localStorage에 저장

Product 데이터:

Product={
price: 119,
sold: 0,
title: "시티 마라톤 PT - 베이지:네이비 / D67397 ",
updatedAt: "2021-08-20T15:51:21.251Z",
...

Product 데이터는 위와 같이 객체 형식으로 저장되어있다.
따라서 Product 객체의 프로퍼티들을 {키:값}으로 해서 localStorage에 저장시켰다.

let data = Product.keys();
for(let i=0;i<data.length;i++){
  window.localStorage.setItem(data[i],Product[i])
}

하지만 이는 너무 비효율적이라 생각해서 다른 방법을 고민해보았다.

[개선 2] 객체를 통째로 localStorage에 저장

개선 1의 방법을 해결하기 위해 방법을 찾던 중, JSON.stringify()JSON.parse()를 발견했다.
이를 사용하여 객체를 통째로 JSON 문자열로 바꾸어 localStorage에 저장하였고, JSON.parse()를 통해 저장한 값을 객체로써 바로 사용할 수 있게 하였다.

useEffect(() => {
  	// 제품 아이디를 키로 가지고 있는 localStorage가 존재하지 않으면,
    if (window.localStorage.getItem(productId) === null) {
      console.log(productId);
      // Axios를 통해 서버에서 제품 데이터를 받아온다.
      Axios.get(`/api/product/products_by_id?id=${productId}&type=single`).then(
        (response) => {
          // 받아온 데이터를 useState(Product,setProduct)에 저장
          setProduct(response.data[0]);
        }
      );
    // 제품 아이디를 키로 가지고 있는 localStorage가 존재하면,
    } else {
      // localStorage에서 데이터를 받아와 seProduct해준다.
      const getData = JSON.parse(window.localStorage.getItem(productId));
      setProduct(getData);
    }
  }, [productId]);
	
	// useState는 비동기적으로 작동해 useEffect를 사용해야 한다.
  useEffect(() => {
    // 페이지에 접속했을 때, Product는 []과 같이 초기화된 상태이므로 예외 처리
    if (Product.length !== 0) {
      // 제품 아이디를 키로 가지고 있는 localStorage가 존재하지 않으면,
      if (window.localStorage.getItem(productId) === null) {
        // Product 데이터를 localStorage에 제품아이디를 키로 하여 저장시킨다.
        const data = JSON.stringify(Product);
        window.localStorage.setItem(productId, data);
        console.log("server"); // 서버에서 데이터 받아옴
      } else {
        console.log("local"); // 로컬에 저장된 데이터 사용
        console.log(productId, Product);
      }
    }
  }, [Product, productId]);

작동 gif


처음 방문했을 때는 로딩 속도가 느렸지만, 다시 방문했을 때부터는 로딩 속도가 매우 증가했음을 확인할 수 있다.

useEffect() 사용

useState는 비동기적으로 작동하기때문에, setProduct한 값을 제대로 가져오기 위해서, useEffect를 사용해 리렌더링을 감소시켰다. (n번->2번)

1 번째 렌더링: 페이지 방문 시
2 번째 렌더링: Product 변경 시

if (Product.length !== 0) 조건문 추가

위에서 useEffect를 사용해 2번으로 렌더링을 줄였지만, 1번째 렌더링 시에 Product값으로 []를 반환해주는 문제가 있었기 때문에(페이지 방문 시에 처음으로 동작하기 때문)
이로 인해 잘못된 값이 localStorage에 들어가는 것을 방지하기 위해 조건문을 추가해 주었다.

📕 결과

제품 페이지에 처음 방문했을 때,

서버에서 데이터를 받아온다.(로딩시간이 길다)

이미 방문했던 제품 페이지를 다시 방문했을 때,

localStorage에 저장된 데이터를 사용(로딩 소요시간 매우 적음)


앞으로 해야할 작업들

컴포넌트 분리 -> 조금 더 용도에 맞게 컴포넌트를 분리시키기
리렌더링 방지
중복되는 코드 합치기
이미지 업로드 기능 추가하기

⭐ 이번 작업 세션 스토리지로 변경하기
https://velog.io/@_jouz_ryul/LocalStorage-SessiongStorage-%EA%B7%B8%EB%A6%AC%EA%B3%A0-Redux-Persist

profile
꾸준하게 공부하기

0개의 댓글