나홀로 리액트 스터디 0.6

Jade·2024년 1월 4일
0

React

목록 보기
6/7
post-thumbnail

요즘은 이전에 작업된 리액트 코드를 보면서 리팩토링을 진행하고 있다
오늘은 메모이제이션, 최적화에 대해서 고민을 해봤는데 마침 딥 다이브에서도 리렌더링에 대한 부분이 나와서 반갑다 🤗

이런 리렌더링 사이클에 대해서 잘 알고 있으면 처음에 컴포넌트를 설계할 때부터 리렌더링을 신경쓰면서 작업할 수 있다는 이야기를 들었는데, 그런 코드를 작성하는 사람에 한 발자국 다가가기 위해 🏃‍♀️

🍩 리액트의 렌더링

브라우저의 렌더링은 'HTML, CSS 리소스를 기반으로 웹페이지에 필요한 UI를 그리는 과정'

리액트의 렌더링은 '리액트 애플리케이션 트리 내에 있는 모든 컴포넌트들이 현재 자신들이 가진 props, state를 기반으로 어떻게 UI를 구성하고, 이를 바탕으로 어떤 DOM 결과를 브라우저에 제공할 것인지 계산하는 일련의 과정'
(props, state가 없으면 컴포넌트가 반환하는 JSX 값에 기반해 렌더링이 일어남)

Render Phase
컴포넌트를 렌더링하고 변경 사항을 계산하는 모든 작업 

Commit Phase 
렌더 단계의 변경 사항을 실제 DOM에 적용해 사용자에게 보여주는 과정 


=> 렌더 단계를 수행하고도 커밋 할 필요가 없을 수도 있음 (리액트 렌더링 !== 무조건 DOM 업데이트)

이런 리액트 렌더링은 항상 동기식으로 작동하므로 렌더링 과정이 길어질수록 애플리케이션 성능 저하 + 브라우저의 다른 작업 지연시킬 가능성 있음


🍩 리액트 렌더링 시나리오

아래 시나리오에 해당하지 않으면 어떤 경우에도 리렌더링을 발생시키지 않는다

1️⃣ 최초 렌더링

2️⃣ 리렌더링 (최초 렌더 이후 일어나는 모든 렌더링)

  • 클래스형 컴포넌트

    • setState 실행시
    • forceUpdate 실행시
  • 함수형 컴포넌트

    • useState의 setState 함수 실행시
    • useReducer의 dispatch 실행시
  • 컴포넌트의 key props가 변경될 때 (ex: map 등으로 순회할 때 부여하는 key props)
    key는 리렌더링이 발생하는 형제 요소들 사이에서 동일 요소를 식별하는 값
    key의 변화가 리렌더링을 일으킨다는 것을 활용해 강제로 리렌더링을 일으키는 것도 가능하다고 함

  • props가 변경될 때

  • 부모 컴포넌트가 렌더링 될 경우
    부모 컴포넌트가 리렌더링 되면 자식 컴포넌트도 무조건 리렌더링이 일어난다


🍩 리액트 패키지가 따로 존재하는 이유

패키지를 설치하려고 보면 간혹 어쩌고-react와 같은 형태로 리액트용 패키지가 따로 존재하는 걸 볼 수 있다
단순히 그냥 사용하는 프레임워크에 따라 다른가보다~ 넘어갔었는데 이런 패키지의 존재도 리액트의 리렌더링과 관련이 있다고 한다

mobx, redux 등은 라이브러리 어딘가에서 각자의 방법으로 상태를 관리하지만
그런 상태의 관리가 리액트의 리렌더링으로 이어지지는 않기 때문에 mobx-react, react-redux 같은 리액트 패키지가 존재하며
반면에 recoil 등은 내부에서 useState를 통해 리렌더링을 발생시킨다고 한다


🧠 메모이제이션

premature optimization 은 금 물 ! (섣부른 최적화라는 영어 단어 줍줍)
리렌더링하는 비용이 더 클지, 저장해둔 데이터를 꺼내오는 게 비용이 더 클지(메모리에 저장하는 비용, 비교하는 비용) 비교가 필요
리액트가 모든 컴포넌트를 PureComponent로 만들거나 모든 컴포넌트를 memo로 감싸지 않고 개발자에게 옵션으로 준 것은 메모이제이션이 모든 문제를 해결하지는 않을 것임을 알게 해준다
반대로 무조건 메모이제이션을 하는 게 더 이득이라는 입장도 책에서 찾아볼 수 있었는데, 이 경우에는 어차피 리렌더링을 할 지 말 지를 결정하기 위해서 props를 비교하는 과정을 거치고, 이는 메모이제이션을 해두고 이전 값과 현재 값이 다른지 비교하는 것과 다를 것이 없다는 것이었다


🕸️ 참고할만한 예제

useQueryString이라는 커스텀 훅이 있는데, 쿼리 스트링과 관련된 함수들을 객분할로 리턴한다
이 커스텀 훅이 여기저기서 계속해서 호출되는 것을 발견했는데, 어떤식으로 메모이제이션을 할 수 있을지 모르겠어서 고민중이었는데
책에서 아래와 같은 사례를 소개해서 남겨둔다

function useMath(number:number){
  const [double, setDouble] = useState(0);
  const [triple, setTriple] = useState(0);
  
  useEffect(() => {
    setDouble(number*2);
    setTriple(number*3);
  },[number]}
  
  return useMemo(() => ({double, triple}), [double, triple])
}
profile
키보드로 그려내는 일

0개의 댓글