[React 성능 최적화] react.memo

김민지·2024년 3월 26일
0
post-thumbnail
post-custom-banner

😴😴그 동안 왜 포스팅을 안 했는가😴😴

[TypeScript] 뉴스 요약 플랫폼 반응형 웹 프로젝트
[React js] 향수 추천 및 아카이빙 PC웹 프로젝트

두 프로젝트를 시작하며 밸로그에 시리즈도 만들는데 아주 오랜 시간 동안 포스팅을 하지 않았다.
1. 개발 도중 디자인을 뒤엎는 상황이 발생(배포를 염두에 둔 프로젝트라 디자인을 보다 예쁘게 바꾸었다.)
2. 늦어진 개발 일정으로 기능 구현에 급급하게 됨(=기록할 만한 기술을 사용하지 못했다. 구현하면서 구글링한 내용은 그저 내가 단순히 사용법을 제대로 몰랐던 것들이었다.)


😐😐그럼 이 포스트는 무엇인가😐😐

1차 개발 및 배포를 끝내고 보니 모든 기능이 잘 동작하고, 디자인도 이쁘니 마음에 들긴 하는데 퀄리티가 이게 맞나라는 생각이 자꾸 들었다. 대기업에서(난 대기업에 다니고 있진 않지만) 이런 수준의 웹사이트를 내놓으면 욕먹을 것 같다는 생각이 들었다.
(+ 포트폴리오에 설명할 것이 없다는 문제도 발생...)
따라서 퀄리티를 높여서 2차 배포를 해야겠다고 마음을 먹었고,
가장 먼저 개발의 ㄱ자라도 공부하고 있는 사람이라면 한 번쯤은 들어보았을 '성능 최적화'라는 것을 해보기로 했다.


🤔🤔그래서 어느 부분을 최적화했는데?(ft.불필요한 렌더링)🤔🤔



응? 북마크 state가 바뀌었을 뿐인데 왜 ShoppingInformationTab이 렌더링된거지?

🌌🪐노파심에 적어놓는데 향수는 절대로 아무데서나 사면 안됩니다. 꼭 정품이 확실한 곳에서만 사야 합니다. 가품 향수에 어떤 것들이 들어가는지 아신다면 헛구역질을 하실거에요.🌌🪐

🚨 북마크와 아무 상관이 없는 ShoppingInformationTab이 북마크 state가 바뀔 때마다 "불필요한 렌더링"이 일어나고 있다. 🚨

API만 중복호출 안하면 되는 줄 알았는데 리액트의 기본 중의 기본!
부모 컴포넌트가 렌더링하면 그 안에 있는 모든 컴포넌트를 렌더링한다는 것을 망각하고 있었다. 망각보다는 실전에 적용을 못한다고 하는 것이 맞지만.



🙋‍♀️🙋‍♀️ 그래서 어떻게 해결했는데? 👉react.memo 🙋‍♀️🙋‍♀️

react.memo라는 것을 사용하면 된다.

방법은 아주 간단하다. 화살표 함수를 사용하는 경우 파라미터 받아오는 부분 앞에 React.memo를 적어주기만 하면 된다. 이렇게 간단한 걸 이제서야 써보다니!

🚨 before 🚨

const ShoppingInformationTab = (
  props: {
    shoppingList: ShoppingInformation[] | null | undefined
  }
) => {
  console.log("ShoppingInformationTab is rendered")

  return (
    <ShoppingInformationTabArea>
      <ShoppingTabTitle>구매 정보</ShoppingTabTitle>
      <WarningBox>
        <WarningTitle>구매 시 유의사항</WarningTitle>
        <WarningContent>
          센카이브는 고객이 쇼핑몰을 통해 구매한 상품에 대해
          <span style={{color:"#D67070"}}> 보증하거나 별도의 책임을 지지 않으며, </span>
          상품의 주문, 결제, 배송, 교환, 환불 등 상품판매와 관련한 일체의 책임은 해당 쇼핑몰에 있습니다.
        </WarningContent>
      </WarningBox>

      <ShoppingSlider shoppingList={props?.shoppingList}/>

    </ShoppingInformationTabArea>

  );
};

export default ShoppingInformationTab;

🍀 after 🍀

// 아래와 같이 컴포넌트를 만들 때 바로 React.memo를 적용하면 된다.
const ShoppingInformationTab = React.memo(
  (props: {
    shoppingList: ShoppingInformation[] | null | undefined
  }) => {

    console.log("ShoppingInformationTab is rendered")

    return (
      <ShoppingInformationTabArea>
        <ShoppingTabTitle>구매 정보</ShoppingTabTitle>
        <WarningBox>
          <WarningTitle>구매 시 유의사항</WarningTitle>
          <WarningContent>
            센카이브는 고객이 쇼핑몰을 통해 구매한 상품에 대해
            <span style={{color:"#D67070"}}> 보증하거나 별도의 책임을 지지 않으며, </span>
            상품의 주문, 결제, 배송, 교환, 환불 등 상품판매와 관련한 일체의 책임은 해당 쇼핑몰에 있습니다.
          </WarningContent>
        </WarningBox>

        <ShoppingSlider shoppingList={props?.shoppingList}/>

      </ShoppingInformationTabArea>
    );
  }
);

export default ShoppingInformationTab;

🤩🤩그래서 결과는 어떻게 되었니?🤩🤩


불필요한 렌더링이 사라졌다!



👮‍♀️👮‍♀️ 근데 당신 다음부터는 react.memo 어디에 쓸지 어떻게 판단할건데? 👮‍♀️👮‍♀️

react.memo를 사용할지 말지 판단하기 위해서는 컴포넌트의 순수성을 확인할 필요가 있다고 한다. 컴포넌트가 props나 state 외의 외부 데이터에 의존하지 않고, 전달받은 props에만 의존하는 경우에 적합하다고 한다.
오늘 react.memo를 적용해본 ShoppingInformationTab도 순수 함수형 컴포넌트였다!

react.memo를 시작으로 프로젝트 성능 최적화를 위해 노력해보겠다.
규모가 작아서 할 것이 많진 않지만!

profile
이건 대체 어떻게 만든 거지?
post-custom-banner

0개의 댓글