유저들은 아주 작은 속도에도 굉장히 민감하게 반응을 합니다.
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 비교는 불필요하게 됩니다.
원본 내용 : dmitripavlutin.com/use-react-memo-wisely/
'이유's Programming > JavaScript' 카테고리의 다른 글
함수형 프로그래밍에 대한 introduction / 선언형 프로그래밍/ 함수형 프로그래밍/ functional programming (2) | 2021.08.12 |
---|---|
Redux 에서 Mobx 상태관리 도입기 - 참고 (0) | 2021.03.23 |
[ 구글 채널 ] Scheduling Tasks - HTTP 203 (1) | 2021.03.02 |
자바스크립트 MAP - array 는 배열로 관리하기. / array 를 key 로 접근 (0) | 2021.01.23 |
5강 Class (0) | 2020.07.11 |