프론트엔드 개발자가 되기위한 여정 -31

이정우·2022년 10월 17일
0

frontend-bootcamp

목록 보기
33/60

밸! 하!

밸로그 여러분 안녕하세요

오늘부터 성능최적화에 대해서 알아보겠습니다
성능최적화 방법에는 여러가지가 있는데요

오늘은
그중에서
memoization,promise all과 브라우저 렌더링(preload/prefetch)에 대해서 알아보겠습니다!

먼저

memoization이란 무엇일까요??

memoization이란

memoization이란 말 그대로

  • 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술
    이라고 할수있습니다

    메모이제이션 -나무위키

기존에 저희가 react를 사용할때 state를 사용하거나 let을 사용하여 변수를 지정해주고 값을 담아줬었죠??
그런데 state의 값이 변할때마다 리렌더링되며 let에 있는 값들이 초기화되어 다시 불러와지며 메모리를 많이 사용하는 경우가 있습니다
말로는 조금 어렵죠?
그럼 한번 코드로 봐볼까요??

export default function MemoizationParentPage() {
  console.log("부모가 렌더링 됩니다");

  let countLet = 0;
  const [countState, setCountState] = useState(0);



  const onClickCountLet = () => {
    console.log(countLet + 1);
    countLet += 1;
  };

  const onClickCountState = () => {
    console.log(countState + 1);
    setCountState(countState + 1);
  };

  return (
    <>
      <div>======================</div>

      <div>카운트(let):{countLet}</div>
      <button onClick={onClickCountLet}>카운트(let)+1 올리기</button>

      <div>카운트(state):{countState}</div>
      <button onClick={onClickCountState}>카운트(State)+1 올리기</button>

      <div>======================</div>
    </>
  );
}

이렇게 되게된다면
let을 사용한 카운트를 눌러서 콘솔의 값이 올라가는것을 확인할수있습니다

하지만 이때 state를 눌러서 state의 값을 늘리게 된다면
let 으로 카운트 한값이 초기화 된것을 볼 수 있습니다
이렇게 되면 메모리에 새로운값이 계속 쌓이게 되는것이고
어느순간에는 메모리가 다 차서 잠깐 멈추면서 메모리가 정리가 되곘죠?
이런 메모리 낭비를 막기위해서 쓰는것이
바로
memorization입니다

그럼 어떻게하면 메모리를 한개만 사용할수있을까요?

export default function MemoizationParentPage() {
  console.log("부모가 렌더링 됩니다");

  let countLet = 0;
  const [countState, setCountState] = useState(0);

  // 1. useMemo로 변수 기억
  const aaa = useMemo(() => Math.random(), []);
  console.log(aaa);


 const onClickCountState = () => {
     console.log(countState + 1);
     setCountState((prev) => prev + 1);
    };



  return (
    <>
      <div>======================</div>

      <h1>저는 부모컴포넌트 입니다</h1>

      <div>카운트(let):{countLet}</div>
      <button onClick={onClickCountLet}>카운트(let)+1 올리기</button>

      <div>카운트(state):{countState}</div>
      <button onClick={onClickCountState}>카운트(State)+1 올리기</button>

      <div>======================</div>
    </>
  );
}

자 이렇게 useMemo라는것을 사용하게 된다면
메모리를 한개만 사용하고
이 저장된 메모리에 값을 지속적으로 불러와서
메모리 사용을 낮출수 있고 성능또한도 늘릴수 있겠죠??

자 그럼 이번에는 한번
이 부모컴포넌트에 자식컴포넌트를 넣어볼까요??

export default function MemoizationParentPage() {
  console.log("부모가 렌더링 됩니다");

  let countLet = 0;
  const [countState, setCountState] = useState(0);

  // 1. useMemo로 변수 기억
  const aaa = useMemo(() => Math.random(), []);
  console.log(aaa);


 const onClickCountState = () => {
     console.log(countState + 1);
     setCountState((prev) => prev + 1);
    };



  return (
    <>
      <div>======================</div>

      <h1>저는 부모컴포넌트 입니다</h1>

      <div>카운트(let):{countLet}</div>
      <button onClick={onClickCountLet}>카운트(let)+1 올리기</button>

      <div>카운트(state):{countState}</div>
      <button onClick={onClickCountState}>카운트(State)+1 올리기</button>

      <div>======================</div>
            <MemoizationChildPage />
    </>
  );
}

자 이렇게 된다면은

값이 변경 될때마다 지속적으로 MemoizationChildPage이라는 컴포넌트를 불러오게되겠죠?
이렇게 되면 앞서 이야기 드린것처럼 메모리가 지속적으로 사용되지 않겠습니까?

그래서 이때는 어떻게 해야하나

React에서는 이럴때를 위해 Memo라는 HOC를 제공해 줍니다!
HOC가 무엇인지 잘 모르시는 분들은
HOCHOF
를 한번 보고 오시면 좋을것 같아요!

자 이렇게 한다면 어떻게 사용하면 될까요?

먼저 자식페이지의 코드를 봐보겠습니다


export default function MemoizationChildPage() {
  console.log("자식이 렌더링 됩니다");

  return (
    <>
      <div>======================</div>
      <h1>저는 자식 컴포넌트 입니다</h1>
      <div>======================</div>
    </>
  );
}

이런 상태에서
메모리의 낭비를 막기위해
react에서 지원하는 memo라는 HOC를 써야한다고 했죠??

한번 적용해 볼까요??

import { memo } from "react";
function MemoizationChildPage() {
  console.log("자식이 렌더링 됩니다");

  return (
    <>
      <div>======================</div>
      <h1>저는 자식 컴포넌트 입니다</h1>
      <div>======================</div>
    </>
  );
}

export default memo(MemoizationChildPage);

자 이렇게 적용할수 가있습니다

React에서 제공하는 Memo라는것을 사용한 이후
다시 실행해주게 된다면

놀랍게도 부모컴포넌트에서 실행을 하여도 한번만 호출이 되는것을 알수 있습니다
이렇게 된다면 자식페이지로 넘어가기전까지는 그 페이지가 저장이되어서 담겨있는것을 볼 수 있겠죠?
그렇다면 또한 메모리사용량도 줄게되고 성능또한도 향상되겠죠!

다만, 넘겨주는 props가 기존것과 다르다면 리렌더링이 되게됩니다!

즉 자식컴포넌트의 dependency array가 props라고 할수 있습니다!

자 그러면 훨씬 이해가 쉽겠죠?

그러면 이렇게 효율성이 좋다고 한다면 모든 컴포넌트에 Memo를 붙이면 될까요?

만약 그렇다면은 React에서 자체적으로 만들어져 나왔겠죠?

왜 안 만들어져서 나왔을까요

그 이유는 바로 쓸데없이 메모리를 낭비하게 될수도 있기 때문입니다
예를들어
부모 컴포넌트가 리렌더링이 되지가 않는데 자식컴포넌트에 메모를 달게 된다면
리렌더링이 되지않는데 두번을 저장하게 되어서 메모리를 낭비하게 된다는거죠!

조금 이해가 되셨나요??
그럼 이제 Memo를 어떻게 쓰는지 조금은 알아가셧죠??

오늘의 포스팅은 여기까지! 입니다

오늘은 Memoization에 대해 알아보았는데요
memoization은 알고리즘에서는 재귀를 뜻하지만 그것이 아닌 React내부에서는
memo라는것을 통해서
메모리에 저장하고 쓸데없는 메모리 낭비를 하지 않을수있다했죠
그리고 사용시 주의 할 점으로 리렌더링이 되지 않는 페이지에서는 memo를 사용하게되면 오히려 메모리를 낭비하게 된다고 했다는거 잊지 않으셨으면 좋겠습니다~

오늘도 지식한개 채워가볼까요~

그럼 이만!

밸~바!

profile
주니어 프론트엔드 개발자

0개의 댓글