0. 사용 이유
✍ 리플로우와 리페인트
브라우저가 렌더링 된 후 모종의 이유로 레이아웃이 변경될 때 마다 브라우저는 렌더링 된 부분을 업데이트 하는 과정에서 전체 화면을 다시 렌더링하게 된다. 이 과정에서 '리플로우(Reflow)'와 '리페인트(Repaint)'가 발생하게 된다.
리플로우( Layout )
- 렌더 트리의 노드들이 뷰포트 내에서 어떻게 위치되어야 하는지 정보를 계산하는 단계.
- 이 단계를 통해 디자인 속성을 픽셀 단위로 변환.
리페인트( Paint )
- 렌더 트리에 만들어진 노드를 실제로 화면에 그리는 단계.
- 레이아웃에 영향을 주지 않는 스타일 속성의 변경은 reflow를 수행하지 않고 paint 과정만 수행한다.
- 따라서 가급적이면 리플로우가 발생하는 스타일 수정보다 리페인트가 발생하는 스타일만을 수정하는 것이 성능에 좋다.
✍ 리렌더링
리엑트에서 props와 state가 변경될 때는 다시 렌더링이 발생하게 된다.
이 때 상위 컴포넌트에서 props가 변경되면 하위컴포넌트도 무조건 렌더링이 발생하게 된다.
이런 비효율적인 렌더링을 방지하고자 react.memo를 쓸 수 있다.
1. React.memo()
React.memo()는 실질적으로 변경된 컴포넌트만 DOM에 업데이트 해주는 memo hook이 있다.
react는 HOC 패턴을 사용하는데, memo로 감싼 컴포넌트를 렌더링할 때 이전에 기억하던 결과물을 메모리에 기억했다가 재사용한다(memoization)
1. 현재 구조 특정 부분을 기억해둔다
2. 변경이 발생했을 때 기억해둔 부분과 렌더링되려 하는 부분을 비교한다.
3-1. 변경사항이 발생하지 않았다면 DOM을 업데이트 하지 않는다
3-2. 변경사항이 발생했다면 DOM을 업데이트 한다
✍ 사용 조건
- 퓨어한 함수형 컴포넌트 일 때 사용할 수 있다.
- 자주 렌더링 되는 컴포넌트에 사용해야 이점이 있다(Renders often).
- 똑같은 prop이 계속 렌더링될 때 ( ex - input )
- UI가 큰 사이즈의 컴포넌트일 때
✍ 사용 방법
1.
import {memo} from "react";
const ShowToDoSet = memo(() => {
const [atomGoals, setAtomGoals] = useRecoilState(myProgress);
const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
.
.
.
2.
export default React.memo(ShowToDoSet);
✍ 주의
memo가 필요없는 렌더링을 막아주기는 하지만 이 이점을 보고 모든 컴포넌트에서 memo를 사용하는 것도 좋지 않다.
위에서 설명했듯이, memo는 현재 상태를 메모리에 기억해두고 렌더링 될 때마다 변화된 상태와 메모리에 기억한 상태를 비교한다.
따라서 사용상의 이점이 없는 컴포넌트에 무작위로 memo를 남발하게 되면 효율은 고사하고 필요없는 비용만 발생시킨다.
React.memo는 props의 변화를 감지한다.
따라서 React.memo가 사용된 함수 컴포넌트에서 useSate 등 다른 훅을 사용한다면 state가 변할 때 다시 렌더링 될 수 있다
props가 갖는 깊은 층위의 객체에 대해 얕은 비교( 값 비교 / 주소 값 비교 )만 수행한다.
조금 더 깊은 비교를 위해서는 객체를 단순화하거나 별도의 비교 함수를 두 번째 인자로 사용해야 한다
🙇♀️
https://goongoguma.github.io/2021/09/22/Use-React.memo()-wisely/
https://yohanpro.com/posts/react/react-memo
https://velog.io/@jewoo/React-memo-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
https://intrepidgeeks.com/tutorial/react--usememo-usecallback-reactmemo
'✍ 공부 > React' 카테고리의 다른 글
[ 🐱💻 강의 노트 ] React 완벽 가이드 강의 정리 (0) | 2022.05.26 |
---|---|
React에서 상태관리하기 (자체적 방법과 라이브러리 비교하기 Recoil, Redux) (0) | 2022.04.21 |
[ TIL ] React.PureComponent란 (0) | 2022.04.06 |
[ React Hook Form ] react에서 form 쉽게 이용하기 (+TypeScript) (0) | 2022.04.01 |
React에서 styled-component 이용하기 + typescript (1) | 2022.03.28 |