블로그 Streaming SSR 적용기
1. Navbar가 레이아웃이 아니라 각 페이지에 독립적으로 선언돼있음
원인
/diary와/notes에 각각 다른 레이아웃을 구현하려다보니 그렇게 됨 해결- 디자인을 수정해
<Navbar />를RootLayout에 호출하고,/notes레이아웃에선<Sidebar className='z-10 md:pt-[65px]' />로 겹치는 문제를 패딩으로 해결함 - 최대한 z-index, 레이아웃 CSS로 해결보려 했지만 가변적으로
sticky상태가 되는Navbar에 맞춰Sidebar의 레이어를 조정하는 방법이 올바른 접근 방법인지 모르겠어서 조금 짜치는 해결법 채택
2. /notes 클라이언트, 서버 컴포넌트 분리
문제
- 현재
/notes라우트는 클릭 시에 브라우저 기준 23초, 모바일 기준 510초 멈춘 뒤 렌더가 되고 있음 원인 - 컴포넌트 분리가 정확히 돼있지 않아
/notes페이지를 렌더하는데 필요한 모든 컴포넌트를 한꺼번에 만들어 보내는데 시간이 23초/510초가 소요되는 것 <NoteContent />렌더 페이지가 dynamic routes기 때문에(/[...slug]/page.tsx) 요청마다 굽는 서버사이드 렌더링 적용 중.
/notesㄴ /[...slug] ㄴ page.tsx - NotePage > NoteContent, NoteLoadingㄴ layout.tsx - SidebarProvider > NoteSidebar data={data}, {children}ㄴ note-sidebar.tsx - Tree.tsx, NoteLink.tsx분석
<Sidebar />는 모바일 반응형, 오픈 여부 컨트롤 목적의Context API때문에 클라이언트 컴포넌트일 수밖에 없음<NoteContent />는 정적인 컨텐츠이므로 서버 컴포넌트. 원인에서 짚었듯 SSR 적용 중인데generateStaticParams로 노트 데이터를 가져온다면 SSG가 가능할지도?- 그렇다면 가장 이상적인 모습은 클릭 시 컨텐츠 부분은 바로 보이고, 사이드바 부분은 스켈레톤이 보이다가 하이드레이션되어야 함 해결
- 일단 불필요한
layout.tsx제거하고page.tsx에서<NoteSidebar />호출하기- Layouts do not rerender. 따라서 매번 리렌더돼야하는 사이드바는 의미가 없다
generateStaticParams에서 note 데이터 전처리해 뿌려주기.
근데 사이드바도 사실 오픈 컨트롤, 모바일 반응 제외하면 static한 컨텐트인데.. 서버컴포넌트로 바꿀 순 없는걸까? reddit comment: "So client components still get rendered on the server. The difference is, once they end up on the client, they can be hydrated and provide interactivity. If you pass all the required data through props from a server component (i.e. not data fetching in a use effect or some other client side method like trpc/react query/swr) the full contentful load of that client component will be rendered on the server."