일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 마사지
- 유효성검사
- JavaScript
- 중고거래사기
- 자동완성
- plugin
- 정규식
- REACT
- 사기
- 삼성무선청소기제트
- 중고나라
- 스쿠버다이빙
- 해외여행
- autocomplate
- Webpack
- Hooks
- 정직하게사세요
- 막탄
- 여행
- js
- ES6
- 세부
- webpack.config.js
- 구분
- 맛사지
- 특수문자
- 중고나라사기
- 스노쿨링
- 네이버페이사기
- Today
- Total
Ryu.log
[React] 성능최적화 (React.memo() 사용팁 정리) 본문
React.memo() 사용팁 정리
Created: Apr 14, 2021 10:27 AM
Tags: React, javascript
요약: React.memo() 사용 팁
React.memo() 사용 팁 정리
React에서는 UI성능 증가를 위해 **React.memo()**
를 지원한다.
React.memo()
**React**
에서는 먼저 컴포넌트를 랜더링 한 뒤,
이전 랜더링 된 결과와 비교하여 랜더링 결과가 이전과 다르다면, DOM
을 업데이트 한다.
export function User({ name, data }) {
return (
<div>
<div>name: {name}</div>
<div>data: {data}</div>
</div>
);
}
export const MemoizedUser = React.memo(User);
React.memo()
로 User
컴포넌트를 래핑하게 되면, React
는 컴포넌트를 랜더링 하고,
그 결과를 메모이징(Memoizing) 한다.
그 뒤, 다음 랜더링이 일어났을 때 해당 컴포넌트의 props가 같다면,
React는 메모이징 된 내용을 재사용한다.
메모이징 한 결과를 재사용 함으로써, React는 리랜더링 시 가상 DOM에서 달라진 부분을 확인하지 않아 성능이 향상 될 수 있다.
props 비교 커스터마이징
React.memo()
는 props
혹은 **props**
의 객체를 비교할 때 얕은 비교를 한다.
깊은 비교 방식이나 다른 방식으로 수정하고 싶을 땐 React.memo()
의 두번째 매개변수로 비교함수를 만들어 넘겨주면 된다.
export function User({ name, data }) {
return (
<div>
<div>name: {name}</div>
<div>data: {data}</div>
</div>
);
}
function userPropsEqual(prevUser, nextUser) {
return prevUser.name === nextUser.name && prevUser.data === nextUser.data
};
export const MemoizedUser = React.memo(User, userPropsEqual);
userPropsEqual()
함수는 prevProps
와 nextProps
가 같다면 true
를 반환할 것이다.
위와같은 방식으로 두번째 매개변수에 비교함수를 넘겨주면 좀 더 상세한 비교가 가능해진다.
React.memo()를 사용해야할 때와 하지말아야 할 때
사용해야 할 때
- 컴포넌트가 같은 props로 자주 랜더링 될거라 예상될 때.
사용하지 말아야 할 때
성능 관련 변경이 잘못 적용 된다면 성능이 오히려 악화될 수 있다. **React.memo()**
를 현명하게 사용해야 한다.
- 컴포넌트가 다른 props로 자주 랜더링 될거라 예상될 때. (쓸데없는 props 비교)
- 대부분의 결과가 다르다면 메모제이션 기법의 이점을 얻기 힘들다.
어짜피 결과가 다르니React.memo()
의 비교함수의 대부분은 false를 반환, 리랜더링이 일어날 것이고, React.memo()
*로 래핑하지 않은 컴포넌트와 비교 시, 오히려 이전**props**
와 현재props
의 비교작업이 추가되기 때문이다.
- 대부분의 결과가 다르다면 메모제이션 기법의 이점을 얻기 힘들다.
React.memo() 와 콜백함수 주의사항
함수 객체는 "일반" 객체와 동일한 비교원칙을 따른다.
함수 객체는 오직 자신에게만 동일하다
function sumFactory() {
return ( a, b ) => a + b;
}
const sum1 = sumFactory();
const sum2 = sumFactory();
console.log(sum1 === sum2); // false
console.log(sum1 === sum1); // true
console.log(sum2 === sum2); // true
**sumFactory()**
함수는 2가지 숫자를 더해주는 화살표 함수를 반환한다.
sum1
과 sum2
두가지 모두 sumFactory()
에 의해 생성된 함수이지만. sum1
과 sum2
는 각각 다른 함수 객체이다.
부모 컴포넌트가 자식 컴포넌트에게 Props로 콜백함수를 전달할 때, 새 함수가 암시적으로 생성될 가능성이있다.
function Logout({ name, onLogout }) {
return <div onClick={onLogout}>Logout {name}</div>;
}
const MemoizedLogout = React.memo(Logout);
function UserContainer({store, cookies}) {
return (
<div className="main">
<header>
<MemoizedLogout
name={store.name}
onLogout={() => cookies.clear()}
/>
</header>
{store.content}
</div>
);
}
위 코드에서 동일한 **name**
이 전달 되더라도, **MemoizedLogout**
은 새로운 **onLogout**
콜백 때문에 메모제이션이 되지않고 리랜더링을 하게된다.**onLogout**
**Props**
로 넘어가는 콜백함수가 inline으로 작성되어(프로그램 구동에는 문제가 없지만) 매번 새로 함수 참조값이 생성되기 때문이다.
해당 부분을 정상적으로 메모제이션 하기 위해서는
function Logout({ name, onLogout }) {
return <div onClick={onLogout}>Logout {name}</div>;
}
const MemoizedLogout = React.memo(Logout);
function UserContainer({store, cookies}) {
const onLogout = useCallback(() => {
cookies.clear();
}, []);
return (
<div className="main">
<header>
<MemoizedLogout
name={store.name}
onLogout={onLogout}
/>
</header>
{store.content}
</div>
);
}
**useCallback()**
을 이용하면 콜백 함수의 메모제이션된 버전을 반환 하여, 매번 동일한 콜백 인스턴스를 반환한다.
이를통해 **MemoizedLogout**
의 메모제이션이 정상동작 가능하다.
결론
React
에서는 성능 개선을 위한 하나의 도구로 메모제이션을 사용한다.
대부분의 상황에서 React는 메모이징 된 컴포넌트의 리랜더링을 피할 수 있지만, 랜더링을 막기 위해 메모제이션에 의존하면 안된다.
React.memo()
는 함수형 컴포넌트에서 메모제이션의 장점을 얻게해주는 도구이다.
올바르게 적용 된다면, 변경되지 않은 동일한 props
에 대해 리랜더링 하는것을 막아준다.
다만 콜백 함수를 props
로 사용하는 컴포넌트에서 메모제이징을 할 때 주의해야 한다.
이전과 동일한 콜백함수 인스턴스를 넘기는지 꼭 체크 해야한다.
참고한 사이트
https://ui.toast.com/weekly-pick/ko_20190731
https://velog.io/@yejinh/useCallback과-React.Memo을-통한-렌더링-최적화
'Front-end > React JS' 카테고리의 다른 글
[React] Hooks (1) | 2019.09.26 |
---|