페이지 전환이 답답하다면? Next.js prefetch 적용기

euNung·2025년 5월 2일

Next.js

목록 보기
4/5

🛫 들어가며

프로젝트를 리팩토링 중, 랜딩 페이지에서 메인 페이지로 이동할 때 체감 속도가 살짝 느린 느낌이 들었습니다.

메인 페이지는 로그인 여부에 따라 다른 데이터를 보여줍니다.

  • 비로그인 사용자: 예시 데이터
  • 로그인 사용자: 실제 사용자 데이터

이로 인해 로그인 여부 판단 과정에서 시간이 소요되어 전환 속도에 영향을 준다고 판단했습니다.

이 흐름에서 성능을 개선할 수 없을까 고민하다가,
tanstack-query의 prefetch로 사용자 정보를 미리 받아두면 조금 더 빨라질 수 있겠다는 생각이 들었습니다. 직접 적용해보고, 성능 측정까지 진행한 경험을 공유합니다.


♟️ prefetch 적용 방식

랜딩 페이지는 아래와 같이 서버 컴포넌트 + 일부 클라이언트 컴포넌트로 구성되어 있습니다.

export default function Page() {
  return (
    <>
      <LandingView >         // 서버 컴포넌트
        <StartButton />      // 클라이언트 컴포넌트
      </LandingView>
      <LandingTracking />    // 클라이언트 컴포넌트
    </>
  );
}

처음에는 서버 컴포넌트에서 prefetch를 적용하려고 했습니다.
서버 컴포넌트에서 prefetch를 진행한 후에는 hydration을 통해 클라이언트로 직렬화를 해야하는데, 랜딩 페이지에서는 유저 정보를 사용하지 않기 때문에 직렬화를 해야할 이유가 없었습니다.

이에 따라, 클라이언트 컴포넌트에서 useEffect로 초기 렌더링 시 prefetch를 수행했습니다.

  useEffect(() => {
    browserQueryClient?.prefetchQuery({
      queryKey: ['profile'],
      queryFn: getProfile,
      staleTime: 5 * 60 * 1000,
    });
  }, []);

⏳ 성능 측정

측정 방식

성능 비교를 명확하게 하기 위해, 브라우저의 performance.mark()를 사용했습니다.

  • landing-to-main-start: 랜딩 페이지에서 버튼 클릭 시 마킹
  • landing-to-main-end: 메인 페이지 useEffect에서 마킹
  • performance.measure()로 두 지점 간 시간 계산
// 랜딩 페이지
performance.mark('landing-to-main-start');

// 메인 페이지
useEffect(() => {
  // 'landing-to-main-start' 마크가 없는 경우(바로 메인 페이지로 진입한 경우)를 방지
  if (performance.getEntriesByName('landing-to-main-start').length > 0) {
    performance.mark('landing-to-main-end');
    performance.measure(
      'LandingToMain',
      'landing-to-main-start',
      'landing-to-main-end',
    );
  }
}, []);

측정 환경

  • Chrome 시크릿 모드
  • DevTools -> Network 탭 - Disabled Cache 활성화
  • Vercel Preview 배포 환경

결과 비교

  • prefetch 미적용
    prefetch 미적용 결과

  • prefetch 적용
    prefetch 적용 결과

prefetch 수행 여부1차(Cold Start)2차3차
X (미적용)2.61s688.5ms615.53ms
O (적용)1.92s565.88ms562.54ms

👉 Cold Start에서 약 700ms, Warm Start에서는 평균 80ms 이상 개선된 것을 확인할 수 있었습니다.


💬 마무리

처음에는 단순히 사용자 여부만 prefetch 적용하는 것이 페이지 전환 속도에 영향을 줄 수 있을까? 반신반의 했지만,
직접 테스트해본 결과, 실제로 개선 효과가 있다는 것을 확인할 수 있었습니다.

또한 이번 경험을 통해,performance.mark()를 활용하면 간편하게 정량적 성능 측정이 가능하다는 점을 배울 수 있었습니다.

앞으로도 Suspense, lazy loading, dynamic import 등의 다양한 전략을 고민하여,
더 빠르고 부드러운 사용자 경험을 만들어 갈 수 있도록 고민하고 개선해나갈 것입니다.

profile
프론트엔드 개발자

0개의 댓글