Frontend

[React] useMemo로 실제 메모리 절약해보기

Daejlee 2024. 11. 28. 11:42

리액트의 useMemo 훅은 결과값을 메모리에 저장해놓고 디펜던시 배열에 있는 값이 바뀌지 않는 한 유지되는, 일종의 캐싱 역할을 합니다.

실제로 useMemo를 프로덕션에 적용하여 메모리 절약을 눈으로 확인해볼까요?

AnnouncementItem이 반복되는 공지사항

export default function AnnouncementItem({
  announcementType,
  title,
  date,
  currDate,
  isLast,
}: {
  announcementType: string;
  title: string;
  date: string;
  currDate: Date;
  isLast?: boolean;
}) {
	// useMemo를 쓰지 않을 때
  const diffTime = currDate.getTime() - new Date(date).getTime();
  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  let renderedDate = '';
  if (diffDays < 7) {
    renderedDate = `${diffDays}일 전`;
  } else {
    renderedDate = date;
  }
  return (
    <div
      className={`flex w-full flex-col items-start justify-center text-xs lg:text-sm ${!isLast && 'border-b'} gap-1 lg:gap-2 p-1`}
    >
      <span className="text-baseblue flex w-full flex-row items-center justify-between text-[10px] lg:text-xs">
        <p>{announcementType}</p>
        <p>{renderedDate}</p>
      </span>
      <p>{title}</p>
    </div>
  );
}

위와 같은 공지사항 컴포넌트가 있습니다.

공지사항이 생성된 날짜가 현재 클라이언트 타임존 시간 기준 7일 이내면 n일전, 그 이상이면 날짜를 표시할 겁니다.

날짜를 다루므로 Date 객체를 생성하게 됩니다.

하지만, 이 상태로는 AnnouncementItem 컴포넌트가 10개 렌더링되면 10개의 Date 객체가 생성될 것입니다.

useMemo를 활용하여 메모이제이션 해볼까요?

import { useMemo } from 'react';

export default function AnnouncementItem({
  announcementType,
  title,
  date,
  currDate,
  isLast,
}: {
  announcementType: string;
  title: string;
  date: string;
  currDate: Date;
  isLast?: boolean;
}) {
	// useMemo를 사용할 때
  const renderedDate = useMemo(() => {
    const diffTime = currDate.getTime() - new Date(date).getTime();
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    return diffDays < 7 ? `${diffDays}일 전` : date;
  }, [date, currDate]);
  return (
    <div
      className={`flex w-full flex-col items-start justify-center text-xs lg:text-sm ${!isLast && 'border-b'} gap-1 lg:gap-2 p-1`}
    >
      <span className="text-baseblue flex w-full flex-row items-center justify-between text-[10px] lg:text-xs">
        <p>{announcementType}</p>
        <p>{renderedDate}</p>
      </span>
      <p>{title}</p>
    </div>
  );
}

useMemo 훅을 활용하여 공지사항 게시일인 date, 클라이언트 현재 시간인 currDate를 의존성으로 갖는 rendredDate를 메모이제이션했습니다.