
오늘은 상세페이지 작업중 최적화를 진행하던중 고민했던 부분을 공유해보려합니다.✨

상세페이지를 처음 렌더링 하는 과정에서 다양한 데이터를 페칭하고 있기 때문에 시간이 너무 오래걸리는 문제가 있었어요. 긴 초기 렌더링 시간은 사용자의 이탈의 원인이 되기 때문에 좋은 사용자경험을 위해 꼭 개선해야 했습니다.
상세페이지에서는 게시글에 대한 내용 뿐만 아니라 해당 모임을 신청하거나 찜할 수 있는 Floating Bar도 포함되어 있기 때문에 처음 렌더링 할때 사용자가 이 모임을 이미 신청했거나 찜하기를 했는지, 또는 이 모임의 작성자인지 추가적으로 데이터를 확인하고, 색상을 다르게 표시하는등 차이를 화면상으로 나타내야 했기에 더욱 복잡해졌어요.
상세페이지의 수많은 컴포넌트들을 한번에 표시하려니 과부하가 올 수 밖에 없었죠.
우선 Floating Bar는 스크롤이 긴 상세페이지에서 다른 컨텐츠들 보다 높은 인덱스값을 가지고 있어 페이지 스크롤을 내려도 사용자가 항상 볼 수 있다는 특징이 있어요.
사용자 행동 패턴 분석
이런 분석을 통해 깨달은 점은, 모든 컴포넌트를 처음부터 로드할 필요가 없다는 것이었어요. 특히 Floating Bar는 사용자가 콘텐츠를 먼저 확인한 후에 상호작용할 가능성이 높기 때문에 지연 로딩이 가능한 부분이었습니다.
그렇기 때문에 처음부터 무리하게Floating Bar를 렌더링하며 초기 렌더링 시간을 지체하기보다는 코드를 분리하고 지연 로딩 처리하여 모임의 컨텐츠를 먼저 보여주고 플로팅바를 렌더링해야겠다는 결론을 내렸어요.
React의 lazy와 Suspense를 활용하여 코드 스플리팅과 지연 로딩을 구현하기로 결정했어요.
import { Suspense, lazy } from "react";
// 컴포넌트 지연 로딩
const LikeButton = lazy(() => import('./LikeButton'));
const JoinButton = lazy(() => import('./join/JoinButton'));
export const FloatingBar = ({ onHeartClick, onJoinClick, isLiked, isJoining, /* 기타 props */ }: IFloatingBar) => {
return (
<div className="fixed bottom-0 z-50 w-full mx-auto p-4 bg-background200 shadow-2xl rounded-2xl xs:max-w-screen-xs">
<div className="flex items-center gap-3">
{/* 찜하기 버튼 */}
<Suspense fallback={<div className="w-[72px] h-14 bg-gray100 rounded-2xl animate-pulse" />}>
<LikeButton onHeartClick={onHeartClick} isLiked={isLiked} />
</Suspense>
{/* 신청하기 버튼 */}
<Suspense fallback={<div className="flex-1 h-14 bg-gray400 rounded-2xl animate-pulse" />}>
<JoinButton onJoinClick={onJoinClick} isJoining={isJoining} /* 기타 props */ />
</Suspense>
</div>
</div>
);
};
✔ 컴포넌트 분리와 지연 로딩
-LikeButton과 JoinButton 컴포넌트를 lazy를 사용해 비동기적으로 로드하도록 설정했어요. 페이지 주요 콘텐츠가 먼저 로드되어 사용자가 더 빨리 모임 정보를 확인할 수 있게 되었어요.
✔ Suspense와 로딩 UI
-각 버튼이 로드되는 동안 사용자에게 보여줄 fallback UI를 Suspense로 감싸 제공했어요.
-animate-pulse 클래스를 활용해 로딩 중임을 간단한 애니메이션으로 표현했어요.

위처럼 상세페이지의 Largest Contentful Paint(LCP) 시간도 크게 개선되었답니다!
사용자 경험 개선에서 시작된 이번 고민은 코드 스플리팅과 지연 로딩이라는 해결책을 통해 사용자에게 더 빠르고 자연스러운 경험을 제공할 수 있었습니다🙌
참고)
https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading