Skip to content

렌더링 최적화에 대하여 (by 최적화무새)

Soobeen Yoon edited this page Nov 27, 2022 · 10 revisions

계기

  • 현재 기획에 각 Todo에 대한 소요시간을 측정하는 기능이 있었다.
  • 초 단위로 timer를 설정하려고 했기 때문에, start 버튼을 누르고 end를 누를 때까지 timer가 계속 작동한다.
  • 이를 화면에 표시하기 위해 소요시간을 state로 관리했으며, '소요시간' 출력 부분이 1초마다 리렌더되어야 하므로 리렌더 범위를 최소화하고자 했다.

1. React.memo 사용

  • 최하위 컴포넌트들 (Button, Text 등)은 부모 컴포넌트가 바뀌었을 때에 무조건 렌더링된다.
  • 자녀 컴포넌트가 변하지 않았는데 불필요한 렌더링을 계속 하는 문제를 React.memo로 해결할 수 있다.
  • 최적화된 컴포넌트를 리턴하여 렌더링이 될 상황에 Prop check 수행, Props 변화가 있을 때만 렌더링하도록 설정함.
export default memo(Image);

before

after

🧐 아주 미약하게 렌더링 범위가 축소된 것을 볼 수 있다.

React.memo 적용 소스코드

하지만 최적화무새에게는 아직 부족하지..

문제 인식

  • prop는 원시 타입이 아니면 함수형 컴포넌트(부모)가 렌더링될 때마다 prop이 새로운 object이기 때문에 memo(Child); 해도 제대로 작동 안 할 수 있다.
  • 이러한 경우에는 useMemo Hook과 함께 써야 최적화가 가능하다.

2. useMemo Hook과 함께 쓰기

스크린샷 2022-11-26 오후 10 49 29
const startPauseButton = useMemo(() => {
    return <Button context={<Image src={buttonConfig.src} />} onClick={handleOnToggle} />;
  }, [buttonConfig.src]);

  const postponeDoneButton = useMemo(() => {
    return (
      <>
        <Button context={<Image src={Postpone} />} />
        <Button context={<Image src={Done} />} />
      </>
    );
  }, []);

useMemo Hook으로 개선된 소스코드

하지만 더덕더덕 붙어있는 useMemo 코드들과 Time interaction container가 통째로 재렌더링되는 것은 컴포넌트 분리로 문제를 해결해야 할 것 같았다..

image

3. 컴포넌트 분리하기

  • 이제야 속이 좀 후련해졌다. 근데 버튼 1초마다 렌더링되는거 좀 불-편하다.. (timer와 상태를 공유하고 있어서 그런듯)
  • 컨테이너 전체 -> 각각의 컴포넌트들로 렌더링 범위가 축소되었다.
스크린샷 2022-11-26 오후 11 31 52

여기까지의 소스코드

느낀점

  • 적당한 컴포넌트 분리와 적당한 메모이제이션을 통해 렌더링 최적화를 할 수 있다.
  • 다만, 최적화를 '얼마나' 해야 하는가에 대한 부분은 지속적인 고민이 필요한 것 같다. 과한 분리, 과한 메모이제이션은 오히려 오버엔지니어링 + 성능 저하를 야기하니 말이다.!

💊 비타500

📌 프로젝트

🐾 개발 일지

🥑 그룹활동

🌴 멘토링
🥕 데일리 스크럼
🍒 데일리 개인 회고
🐥 주간 회고
👯 발표 자료
Clone this wiki locally