React는 기본적으로 컴포넌트를 렌더링하고 이전 렌더된 결과와 비교해서 렌더 결과가 다른 경우에만 DOM을 업데이트한다.
이 때, React.Memo()
를 사용하면, React는 컴포넌트를 렌더링 한 후, 이 결과를 Memoizing해둔다.
메모이징이란?
기존에 수행한 연산의 결과 값을 어딘가에 저장해두고 동일한 입력이 들어오면 재활용하는 기법을 말한다.
그리고 다음 렌더링 시, props가 이전과 같다면 메모이징된 내용을 재사용한다.
React에서는 기본적으로 리렌더링 시, 가상 DOM에서 달라진 부분을 확인해서 DOM을 업데이트한다고 했다.
하지만 Memoziation을 사용하면 props가 변경되지 않는 한, 메모이징한 결과를 재사용하기 때문에 가상 DOM에서 달라진 부분을 확인하는 것에 리소스를 사용하지 않기 때문에, 이 부분에서 성능상의 이점을 누릴 수 있다.
이제부터 나의 활용기를 소개해보겠다.
나는 이번 토스 NEXT 사전과제를 통해서 많은 것을 배웠다.
그 중에서도 UI 컴포넌트를 쪼개서 사용하는 방식에 대해서 배웠는데 Text
, Icon
, Input
등등 그리고 Spacing
까지 컴포넌트화를 해서 사용하는 것을 보고 이를 다음 프로젝트에 적용해보아야겠다고 생각했다.
그래서 이번에 진행하는 숭차로 프로젝트
에서 디자이너님께 디자인 리소스들을 잘 쪼개달라고 부탁드리고 이에 맞춰서 재사용 컴포넌트들을 만들고 있다. (미니 디자인 시스템..?)
이에 관한 내용은 또 다른 포스트에 정리해서 올려보겠다!
지금은 그 중에서도 Spacing
컴포넌트에 대해서 말해보려고 한다.
Spacing 컴포넌트란?
props로 입력된direction
과size
의 값에 따라서 칸과 칸을 분리해주는 것
대다수의 경우에, 두 값 모두 정적인 값으로 부모 컴포넌트에서 props로 넘겨주고 변경되지 않을 것이다.
Spacing
같은 경우는 한 번 렌더되면 리렌더링이 대다수의 경우에서 불필요한 컴포넌트이다.
그렇기 때문에 위에서 열심히 설명한 React.Memo()
를 사용하는 경우에 해당될 것이다.
만약 React.Memo()
를 사용하지 않으면, 부모 컴포넌트가 리렌더될 때 계속해서 같이 리렌더될 것이고 이는 불필요하다.
따라서 React.Memo()
를 사용해주는 것이다.
<사용 코드>
import StyledSpacing from '@/styles/StyledSpacing';
import { HTMLAttributes, memo } from 'react';
interface Props extends HTMLAttributes<HTMLDivElement> {
children?: never;
direction?: 'horizontal' | 'vertical';
size: number;
}
export const Spacing = memo(function Spacing({ direction = 'vertical', size, ...props }: Props) {
return <StyledSpacing direction={direction} size={size} />;
});
이렇게 사용해주면 부모 컴포넌트에서 리렌더링이 일어나더라도 direction과 size 값이 변하지 않으면 해당 컴포넌트는 메모이제이션을 해둔 컴포넌트를 사용할 것이다.
나중에 세 가지를 비교한 내용을 정리해서 올려보겠다!
메모이제이션 방식을 사용하는 것이 항상 옳은 것은 아니다.
만약에 필요한 상황
위와 같은 상황들이 아니라면, 사용하지 않는 편이 불필요한 비교 연산을 줄이고 버그를 줄이는데 도움이 될 것이다!
React.Memo()
는 남용하지 않고 필요한 경우에만 현명하게 사용하도록 하자!
References:
https://ui.toast.com/weekly-pick/ko_20190731
https://react.vlpt.us/basic/19-React.memo.html
정보 감사합니다.