logo

DowanKim

30. 의미없는 메모이제이션은 오히려 손해다.

2025년 10월 30일

이게머니

13주차 고생 많으셨습니다!

코드 품질이 많이 좋아진 것 같다고 느꼈어요.

미구현한 부분까지 모두 완성하시고 시간이 남으신다면 aria-label 속성을 추가해서 접근성 개선해보는 것을 추천드립니다.

코멘트 남긴 부분 확인해보시고 수정해주세요!

1. sortedByPoint와 top3까지 메모이제이션할 필요가 있을까요?

const { arranged, rankLabels } = useMemo(() => {...}, [...]) 형식으로 사용해보는 것은 어떨까요?

export const useTopRankList = (topRankingUsers: RankingUser[]) => { const sortedByPoint = useMemo( () => [...topRankingUsers].sort((a, b) => b.point - a.point), [topRankingUsers], ); const top3 = useMemo(() => sortedByPoint.slice(0, 3), [sortedByPoint]); const arranged = useMemo(() => { const [first, second, third] = top3; return [second, first, third].filter(Boolean) as RankingUser[]; }, [top3]); const rankLabels = useMemo(() => { const labels = [2, 1, 3]; return labels.slice(0, arranged.length); }, [arranged]); return { arranged, rankLabels }; };

현재 코드를 보면 여러 문제가 있는 것 같습니다.

1. 최종반환값이 아닌 sortedByPoint와 top3가 메모이제이션 되고 있습니다

이 값들은 외부에서 사용하지 않고 arranged와 ranklables계산에만 사용되기 때문에, 딱히 큰 의 미없이 useMemo를 사용하고 있는 것 같습니다.

2. 결국에는 네번과정 다 다시 계산해야 됩니다.

topRankingUsers가 변경되면, 그 이후 의존성이 다 체이닝 되어있기 때문에, 결국 다 다시 계산합니다.

3. useMemo로 얻는 이득이 크지 않은 것 같습니다.

slice(0,3) 은 메모하는게 오히려 더 성능적으로 손해인것 같습니다.

arranged또한 사실 메모하는게 더 성능적 손해 같습니다.

const { arranged, rankLabels } = useMemo(() => { const sortedByPoint = [...topRankingUsers].sort((a, b) => b.point - a.point); const top3 = sortedByPoint.slice(0, 3); const [first, second, third] = top3; const arranged = [second, first, third].filter(Boolean) as RankingUser[]; const labels = [2, 1, 3]; const rankLabels = labels.slice(0, arranged.length); return { arranged, rankLabels }; }, [topRankingUsers]);

사실상 이렇게 useMemo를 한번만 사용하고, 중간과정은 안에 다 포함시키는게

  • 네번 메모이제이션 하는 것 보다 훨씬 성능이 좋습니다
  • 불필요한 중간계산은 보관하지 않습니다