[React] react-tooltip 렌더링 성능 최적화

react-tooltip 성능 저하 이슈

프로젝트 진행 중에 데이터는 빨리 불러오는데 렌더링까지 오랜 시간이 걸리는 이슈가 있었다. 코드를 살펴보다가 react-tooltip 코드가 문제였다는 것을 발견했다.

 

React Tooltip BAD Case

// ❌ BAD
<div className="items-container">
  {myItems.map(({ id, content, tooltip }) => (
    <div key={id} className="item" data-tooltip-id={`tooltip-${id}`}>
      {content}
      <Tooltip id={`tooltip-${id}`} content={tooltip} />
    </div>
  ))}
</div>

 

`events`의 모든 항목마다 `Tooltip` 컴포넌트를 생성하고 있던 것이 성능 저하의 이유였다.

 

불필요하게 많은 양의 <Tooltip /> 컴포넌트를 사용하는 것은 피해야 합니다. 대부분의 경우 전체 애플리케이션에서 사용하는 하나의 툴팁 컴포넌트로 충분합니다.

react-tooltip의 공식 문서에도 내 코드와 똑같은 예시를 들며 지적하고 있다.

 

프로파일러로 렌더링 속도를 측정해 보면 31ms가 걸렸고, 초기 로딩 시에 수많은 `Tooltip` 컴포넌트가 렌더링된 것을 볼 수 있다.

 

React Tooltip GOOD Case

// ✅ GOOD
<div className="items-container">
  {
    myItems.map(({ id, content, tooltip }) => (
      <div
        key={id}
        className="item"
        data-tooltip-id="my-tooltip"
        data-tooltip-content={tooltip}
      >
        {content}
      </div>
    ))
  }
</div>
<Tooltip id="my-tooltip" />

`Tooltip` 컴포넌트가 한 개만 렌더링 될 수 있도록 `map()`에서 벗어나 상위 요소로 이동했다. 공식 문서에서는 애플리케이션의 루트 컴포넌트(일반적으로 `App.jsx/App.tsx`)에 `Tooltip` 컴포넌트를 배치하는 것을 권장하고 있다.

 

툴팁의 내용은 hover할 대상에서 작성하고, 해당 요소와 `Tooltip` 컴포넌트가 `id`나 `anchorSelect`로 연결되면 `Tooltip` 컴포넌트가 한 개이더라도 툴팁 기능이 정상적으로 작동한다.

 

렌더링 시간이 31ms에서 1.2ms로 줄어들어, 무려 96%를 단축했다.

 

Reference