본문 바로가기

프로그래밍&IT/React & CSS

[Fast Campus , React] 14. React.memo를 이용한 성능 최적화

React.memo를 이용한 성능 최적화

전에 사용한 A, B컴포넌트 비교 소스를 기준으로 성능 체크 및 개선목표.

[Fast Campus , React] 13. 확장프로그램, 성능측정 app 개발

 

B컴포넌트의 문제점?

List, ListItem, Message 컴포넌트로 나뉘어 있는데, 재사용성의 목적도 있지만 각 컴포넌트의 렌더링의 최적화를 위해서이기도 함.

Input에서 글을 쓸 때 원래는 Message 컴포넌트와 그 State를 가지고 있는 App 컴포넌트만 렌더링이 되어야 하는데,

상관이 없는 다른 부분까지 렌더링 되고 있다.

 

React.memo 적용.

원하는 컴포넌틀르 React.memo로 감싸주면 적용이 된다

const Message = React.memo( ({message}) => {
    return (
        <p>{message}</p>
    )
} )

React.memo로 감싸주고, 타이핑을 하면.

렌더링이 필요치 않은 List, ListItem 컴포넌트는 렌더링이 안 되는 걸 볼 수 있다.

profiler로 성능을 비교해 봐도 좋아진 걸 확인이 가능

 

React.memo()?

React는 컴포넌트를 먼저 렌더링 한 뒤, 이전에 렌더링 된 결과와 비교해 DOM 업데이트를 결정한다.

만약 렌더링 결과가 이전과 다르다면 DOM을 업데이트한다.

이 과정에서 만약 컴포넌트가 memo로 둘러싸여 있다면, React는 컴포넌트를 렌더링 하고 결과를 메모(Memoizing)하며,

다음 렌더링이 일어날 때 렌더링하는 컴포넌트의 props가 같다면, React는 메모된 내용을 재사용한다.

props나 props의 객체를 비교할 때는 얕은 (shallow) 비교를 한다.

props비교방식을 수정하려면,

React.memo()의 2번째 매개변수로 비교함수를 넣어주면 된다.

React.memo(Component, [compareFunction(prevProps, nextProps)]);

function compareFunc(prevProps, nextProps) {
    return (
        prevProps.a === nextProps.a && prevProps.b===nextProps.b
    );
}

렌더링 될 때 props가 다른 경우가 대부분이면 메모이제이션 기법의 이점을 얻기 힘들다.

리렌더링을 막기 위한 도구보다는 성능개선을 위한 하나의 도구로 메모이제이션을 사용한다.

렌더링을 막기 위해 메모이제이션에 너무 의존해선 안된다. (버그 유발 가능성)

React.memo를 사용하는 것이 항상 좋은 것은 아니기에 profiler를 이용해서 성능상 이점 등을 확인해야 한다.

 

Memoization?

주어진 입력값에 대한 결과를 저장함으로써 같은 입력값에 대해 함수가 한 번만 실행되는 것을 보장한다.

 

얕은 비교 (shallow compare)

숫자, 문자열 등 원시 자료형은 값을 비교.

배열, 객체 등 참조자료형은 값 혹은 속성을 비교하지 않고 참조되는 위치를 비교

 

깊은 비교?

객체의 경우에도 값으로 비교한다.

object depth가 깊지 않은 경우 : JSON.stringify() 사용

object depth가 깊은 경우 : Iodash 라이브러리의 isEqual() 사용

 

언제 얕은 비교를 사용하나?

React.memo에서 props비교할때

리액트 컴포넌트가 리렌더링을 하기 전 (state 변경 / 부모 컴포넌트가 렌더링)