만족
[React] Tooltip 컴포넌트 퍼포먼스 (withStyles 성능 오버헤드) 본문
[React] Tooltip 컴포넌트 퍼포먼스 (withStyles 성능 오버헤드)
FrontEnd/React Satisfaction 2021. 8. 30. 21:08
한 컴포넌트에 16개의 Tooltip이 포함되어 있고, 그 컴포넌트(ItemCombination)가 10개 존재했을 때 렌더링을 프로파일링한 차트이다.
ItemCombination은 장착중인 16개의 아이템을 아이콘으로 표시하고, 각각의 아이콘을 Tooltip으로 감싼 형태이다.
코드로 봤을 땐 딱히 성능 저하를 일으킬만한 것이 없어서 왜 느린가 싶었지만,
프로파일링한 결과 material-ui의 컴포넌트들은 withStyle로 감싸져 나가기 때문에
이런 식으로 컴포넌트 내에서 많은 반복을 할 경우 비교적 긴 withStyle의 실행 시간 때문에 성능 저하가 발생한다.
실제로 itemCombination에서 Tooltip을 제거하고 빌드했을 땐 렌더링 시간이 압도적으로 빨라졌다는 것을 알 수 있다.
필요할 때만 Tooltip 렌더링
위 상황에서는 ItemCombination 컴포넌트 한 개당 16개의 툴팁이 렌더링된다.
그러나 툴팁은 어떤 컴포넌트 위에 마우스를 올리면 나타났다가 마우스를 움직이면 사라지므로,
마우스를 움직이지 않을 때는 딱히 렌더링할 필요가 없다.
따라서 다음과 같이 한번 더 래핑해서, 마우스가 올라가 있을 때만 Tooltip을 렌더링하도록 변경했다.
const HoverTooltip = ({ tooltip, children }) => {
const [hover, setHover] = useState(false);
return (
<span
onMouseOver={() => setHover(true)}
onMouseLeave={() => setHover(false)}
>
{hover ? <Tooltip title={tooltip}>{children}</Tooltip> : children}
</span>
);
};
별로 특별할 것은 없다.
child를 span으로 감싼 후, 그 span에 마우스가 올라가면 Tooltip과 children을 렌더링하고
마우스가 빠져나가면 children만 렌더링한다.
실제 퍼포먼스 비교
당연하게도 처음 컴포넌트가 그려져 있을 때는 호버되지 않았기 때문에
Tooltip이 렌더링되지 않아 Tooltip을 사용하지 않았을 때와 비슷한 수준의 퍼포먼스가 나온다.
그렇다면 이제 실제로 hover했을 때 HoverTooltip을 리렌더링이 발생했을 때의 퍼포먼스를 측정해보자.
이 경우에도 역시 withStyles에서 실행시간이 급격히 올라가는 구간이 분명 존재한다.
그러나, 한 번에 16번의 withStyles를 했을 때보다는
마우스를 올렸을 때 딱 한번 리렌더링해서 호출 횟수가 1/16으로 줄었기 때문에
저사양 기기에서도 훨씬 더 안정적으로 UI가 표시된다.
withStyle은 무슨 역할을 할까
일단 with라는 prefix가 있는 것으로 보아 hoc인 것을 유추해볼 수 있다.
실제 코드를 열어보면, 꽤 복잡한 형태를 띄고 있다.
withStyle은 context로부터 내려받은 theme나, 기본 스타일, 커스텀 스타일 등을 option으로 받아 뭉친 후
만들어진 style을 hoc패턴을 이용해 전달받은 컴포넌트에 지정한다.
이 과정이 꽤나 무거운지, 하나만 렌더링했을 때에도 마찬가지로 대부분의 시간을 withStyles가 잡아먹는다.
깃헙 이슈에도 올라왔던 주제인데, 근본적인 해결은 불가능한 모양이다.
아무튼 Tooltip 처럼 반복하지 않아도 되는 withStyle-component들은 최대한 반복하지 않는 편이 좋겠다.
'FrontEnd > React' 카테고리의 다른 글
[React] Scss 사용하기 (0) | 2021.12.26 |
---|---|
[React] react-snap 에서 동적 url 스냅샷에 관한 문제 (0) | 2021.10.12 |
[React] useMemo를 이용한 최적화 (0) | 2021.08.28 |
[React] Lazy Initializing를 사용해 최적화 (0) | 2021.08.26 |
[React] 프로젝트에 Adsense 광고 추가하기 (0) | 2021.08.26 |