이유's Programming/JavaScript

[ React -1 ] React.memo 를 사용하여 컴포넌트 성능 최적화하기 . / React.memo 사용할 때 그리고 사용하지 않을 때 팁 정리

살아가는 이유_EU 2021. 1. 26. 10:39
728x90
반응형

유저들은 아주 작은 속도에도 굉장히 민감하게 반응을 합니다. 

 

100 ~300 의 정말 작은 초 단위도 느낄만큼 유저들은 서비스의 속도에 대해서 아주 민감하네요.

 

이런 UI 를 해결하기 위해서, React 는 higher order component 중 하나인 React.memo 를 제공합니다. 

 

 

1. React.memo() 에 대한 간략한 소개

 

React는 먼저 컴퍼넌트를 렌더링(rendering) 한 뒤, 이전 렌더된 결과와 비교하여 DOM 업데이트를 결정합니다.

 

만약 렌더 결과가 이전과 다르다면, React는 DOM을 업데이트하게 됩니다. 

 

React.memo() 로 감싸져있는 내용을, 리액트는 결과를 먼저 memoizing 하게 됩니다. 다음 렌더전에, 

 

props 의 결과가 똑같다면 react 는 memoizing 을 통해 다음 렌더링을 skipping 하게 됩니다. 

 

아래와 같은 예시를 살펴보시죠! 지금 여기서는 Movie 의 컴포넌트가 React.memo 로 감싸져 있습니다 .

 

export function Movie({ title, releaseDate }) {
  return (
    <div>
      <div>Movie title: {title}</div>
      <div>Release date: {releaseDate}</div>
    </div>
  );
}

export const MemoizedMovie = React.memo(Movie);

해당 내용은 Movie 의 컴포넌트가 React.memo 로 감싸져 있으면서 새로운 meomized 된 컴포넌트인

 

MemoizedMovie 를 return 해주게 됩니다. 

 

// First render. React calls MemoizedMovie function.
<MemoizedMovie 
  title="Heat" 
  releaseDate="December 15, 1995" 
/>

// On next round React does not call MemoizedMovie function,
// preventing rendering
<MemoizedMovie
  title="Heat" 
  releaseDate="December 15, 1995" 
/>

 

2. React.memo() 를 써야하는 케이스

 

리액트 메모를 쓸때를 간략하게 말씀 드리겠습니다. 먼저 도표에 있는 내용을 나열해볼께요. 

1)  함수형 컴포넌트를 사용할 때 ( pure functional component ) 

2 ) 렌더링이 자주 일어날 때 

3) 똑같은 props 로 렌더링이 계속 될 때 

3) 컴포넌트 사이즈의 내용이 중~ 큰 사이즈 이상일 때 

 

2.1 같은 props 로 렌더링이 자주 일어나는 컴포넌트 

위의 예시 중 정말 React.memo() 를 랩핑하는 것의 최고의 케이스는 똑같은 props 로

 

계속 렌더링이 일어난 케이스입니다. 

 

부모 컴포넌트로 받은 같은 props 가 계속 렌더링을 일으키는 상황인 것이죠. 

 

아래의 예시는 MovieViewsRealTime 이라는 부모 컴포넌트를 정의했습니다.

 

위의 부모 컴포넌트에서 title, releaseDate, views 를 넘겨주게 됩니다 .

function MovieViewsRealtime({ title, releaseDate, views }) {
  return (
    <div>
      <Movie title={title} releaseDate={releaseDate} />
      Movie views: {views}
    </div>
  );
}

그렇다면 렌더링은 Movie 와 전혀 상관없는 views 의 값이 변경이 될때도 계속해서 Movie 가 렌더링 될 것입니다. 

// Initial render
<MovieViewsRealtime 
  views={0} 
  title="Forrest Gump" 
  releaseDate="June 23, 1994" 
/>

// After 1 second, views is 10
<MovieViewsRealtime 
  views={10} 
  title="Forrest Gump" 
  releaseDate="June 23, 1994" 
/>

// After 2 seconds, views is 25
<MovieViewsRealtime 
  views={25} 
  title="Forrest Gump" 
  releaseDate="June 23, 1994" 
/>

// etc

하지만 이의 경우는 아래와 같이 React.memo 를 이용하여 해결할 수 있습니다.

 

아까만든 memoized 된 컴포넌트인 MemoizedMovie 를 부모 컴포넌트에 넣어주면 렌더링을 훨씬 줄일 수 있습니다. 

function MovieViewsRealtime({ title, releaseDate, views }) {
  return (
    <div>
      <MemoizedMovie title={title} releaseDate={releaseDate} />
      Movie views: {views}
    </div>
  )
}

또한 memo 사용하기 전에 꿀팁인 profiler 을 이용해서 컴포넌트를 줄일 수 있습니다 .

 

reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab 

3. 언제 React.memo() 를 사용하지 말아야 할까

만약 위에서 언급한 상황에 일치하지 않는다면 메모이제이션을 사용하지 않는 것이 좋습니다. 

 

성능 관련 변경이 잘못 적용 된다면 성능이 오히려 악화될 수 있다. React.memo()  를 현명하게 사용하라. 

3.1 쓸모없는 props 의 비교 

컴포넌트가 다른 props 를 가지고 렌더링을한다고 생각해 본다면,

 

이 경우에는 memoization 이 오히려 이점을 얻어가기가 어렵습니다. 

 

props 가 자주 변하는 컴퍼넌트를 React.memo() 로 맵핑할지라도 React 는 두가 지 작업을 리렌더링 할 때마다

 

렌더링을 해당 작업을 수행할 것입니다. 

 

  • 이전 props와 다음 props의 동등 비교를 위해 비교 함수를 수행한다.
  • 비교 함수는 거의 항상 false를 반환할 것이기 때문에, React는 이전 렌더링 내용과 다음 렌더링 내용을 비교할 것이다.

 

해당 비교함수의 내용은 대부분 false 를반환하기에 props 비교는 불필요하게 됩니다. 

 

 

 

참고 사이트 : ui.toast.com/weekly-pick/ko_20190731#3-%EC%96%B8%EC%A0%9C-reactmemo%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C

 

React.memo() 현명하게 사용하기

유저들은 반응이 빠른 UI를 선호한다. 100ms 미만의 UI 응답 지연은 유저들이 즉시 느낄 수 있고, 100ms에서 300ms가 지연되면 이미 유저들은 상당한 지연으로 느낀다. UI 성능을 증가시키기 위해, React

ui.toast.com

원본 내용 : dmitripavlutin.com/use-react-memo-wisely/ 

 

Use React.memo() wisely

React.memo() increases the performance of functional components by preventing useless renderings. But such performance tweaks must be applied wisely.

dmitripavlutin.com

 

728x90
반응형