유저들은 아주 작은 속도에도 굉장히 민감하게 반응을 합니다.
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 비교는 불필요하게 됩니다.
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
'이유'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 |