logo
PostsInvestingHomebarArticlesAbout

Next.js 13 / 01. Routing

2023.06.14 / 9min

Intro

Next.js 13은 2022.09.26 Release 되었다.

그럼에도 불구하고 스스로 공부할 생각을 하지 않고 버전 올라갔으니 좋겠지라소 막연하게 생각하고 있어서 이참에 공부하려고 한다.

글 내용은 Next.js Docs 페이지를 기준으로 Main Features를 정리하고, 이번 블로그를 Next.js 13으로 구성하면서 알게된 것들을 적어보려고 한다.


TOC

Next.js 13 Main Features

공식 홈페이지 Docs에 나와있는 Main Features을 나열해보았다. 물론 이전 버전의 내용이 포함되어있을 수 있다.

Main FeatureFeature Description
Routing파일 시스템 기반의 라우터는 layouts, nested routing, loading states, error handling 등을 지원하는 서버 컴포넌트로 구축되었다.
RenderingClient 및 Server 컴포넌트를 사용하여 Client-side와 Server-side 렌더링 수행. Next.js는 서버에서 Static와 Dynamic Rendering을 통해 더욱 최적화되었다. Edge 및 Node.js 런타임에서 스트리밍 진행.
Data FetchingReact Components에서 async/await를 지원하여 간소화된 데이터 불러오기(fetching) 가능. React 및 Web Platform에 부합하는 fetch()의 API 제공.
StylingCSS Module, Tailwind CSS, CSS-in-JS 등 선호하는 스타일링 방법 지원
OptimizationsImage, Fonts, Script 최적화를 통해 애플리케이션의 Core Web Vitals과 사용자 경험을 개선.
Typescripttype checking과 컴파일 효율성이 개선되고, 사용자 지정 Plugin와 타입 checker를 통해 타입스크립트에 대한 지원이 향상.
API ReferenceNext.js 전반에 걸친 API 디자인 업데이트.

Routing

terminology-component-tree

  • Tree: 계층 구조를 시각화하기 위한 규칙으로 예를 들어 parent와 children가 components가 있는 tree, a folder structure등이 있다.
  • Subtree: 새 root(first)에서 시작하여 leaves(last)에서 끝나는 tree의 일부다.
  • Root: subtree의 첫번째 node로 root layout와 같은게 있다.
  • Leaf: URL 경로의 마지막 세그먼트로 같이 하위 트리에 자식이 없는 노드다.

terminology-url-anatomy

  • URL Segment: 슬래시로 구분된 URL 경로의 일부.
  • URL Path: 도메인 뒤에 오는 URL의 일부(세그먼트로 구성).

app Router

13 버전으로 오면서 React Server Components로 만들 수 있는 새로운 App Router가 추가되었다.
App Router는 shared layouts, nested routing, loading states, error handling 등을 지원한다.

app 디렉토리에서 만들어지지만 이전 버전에서 사용하던 page 디렉토리와 함께 사용이 가능하여 점진적으로 이전하는게 가능하다.

App Router가 Page Router보다 우선한다. 디렉터리 간 경로는 동일한 URL 경로가 있어서는 안되며 충돌을 방지하기 위해 빌드시기에 오류가 발생한다.

기본적으로 app 내부의 컴포넌트는 React Server Components다. 이는 성능 최적화를 위한 것으로 쉽게 채택할 수 있으며, Client Components를 사용할 수도 있다.


Roles of Folders and Files

파일 시스템 기반 라우터를 사용한다.

  • 폴더로 경로를 정의하며, 경로는 root폴더에서 page.js파일이 포함된 최종 leaf폴더까지 파일 시스템 계층 구조를 따라 중첩된 폴더의 단일 경로다.
  • 파일은 경로 segment(세그먼트)에 표시되는 UI를 만드는데 사용된다.

Route Segments

각 폴더는 경로 segment(세그먼트)를 나타낸다. 각 경로 세그먼트는 URL 경로의 해당 세그먼트에 매핑된다.


Nested Routes

중첩된 경로를 만들려면 폴더를 서로 중첩하면 된다. 예를 들어, app 디렉터리에 두 개의 새 폴더를 중첩하여 새 /dashboard/settings 경로를 추가할 수 있다.

/dashboard/settings 경로는 세 개의 세그먼트로 구성된다:

  • / (Root segment)
  • dashboard (Segment)
  • settings (Leaf segment)

File Conventions

Next.js는 중첩된 경로에서 특정 동작을 하는 UI를 만들 수 있는 파일을 제공한다.

파일명기능
layout해당 세그먼트와 하위 세그먼트가 공유하는 UI
page경로의 고유한 UI와 접근 가능한 경로를 만들어준다.
loading해당 세그먼트와 하위 세그먼트를 위한 Loading UI
not-found찾을 수 없는 페이지의 경우 세그먼트 및 해당 하위 세그먼트에 대한 Not found UI
error해당 세그먼트와 하위 세그먼트를 위한 Error UI
global-errorGlobal Error UI
routeServer-side API endpoint
template리렌더링된 특수한 Layout UI(layout 파일과 다름 주의)
defaultParallel Routes를 위한 Fallbak UI

Component Hierarchy

route segment의 특수 파일에 정의된 React components는 특정 계층 구조로 렌더링된다.

  • layout.js
  • template.js
  • error.js (React error boundary)
  • loading.js (React suspense boundary)
  • not-found.js (React error boundary)
  • page.js or nested layout.js

nested-file-conventions-component-hierarchy

중첩된 경로에서 segment의 components는 상위 segment의 components 안에 중첩된다.

nested-file-conventions-component-hierarchy


Colocation

특수 파일외에도 components, styles, tests등 파일을 app 디렉터리의 폴더 안에 만들 수 있다.
폴더가 경로를 정의하는 반면, page.jsroute.js와 같은 파일만 공개적으로 주소를 지정할 수 있기 때문이다.

project-organization-colocation


Server-Centric Routing with Client-side Navigation

Client-side Routing을 사용하는 page 디렉토리와 달리, App Router는 server-centric routing를 사용하여 Server Components와 data fetching on the server를 제공한다. server-centric routing을 사용하면 클라이언트가 경로 맵을 다운로드할 필요가 없으며 동일한 경로의 서버 컴포넌트를 요청할 수 있습니다. 이 최적화는 모든 애플리케이션에 유용하지만 경로가 많은 애플리케이션에서는 불리할 수 있다.

server-centric이지만 라우터는 Link Component와 함께 client-side navigation을 사용하므로 단일 페이지 애플리케이션의 동작과 유사하다. 즉, 사용자가 새 경로로 이동할 때 브라우저는 페이지를 새로고침하지 않는다. 대신 URL이 업데이트되고 Next.js는 변경되는 세그먼트만 렌더링한다.(only render the segments that change.)

사용자가 앱을 탐색할 때 라우터는 React Server Components payload의 결과를 in-memory client-side cache(인메모리 클라이언트 측 캐시)에 저장한다. 캐시는 경로 세그먼트별로 분할되어 어느 수준에서든 무효화를 허용하고 React의 동시 렌더링(React's concurrent renders.) 전반에 걸쳐 일관성을 보장합니다. 즉, 특정 경우 이전에 가져온 세그먼트의 캐시를 재사용하여 성능을 더욱 향상시킬 수 있다.


Partial Rendering

형제 경로(예: 아래의 /dashboard/settings/dashboard/analytics) 사이를 탐색할 때 Next.js는 변경되는 경로의 레이아웃 및 페이지만 가져와 렌더링한다.

하위 트리의 위 세그먼트에서는 다시 가져오거나(re-fetch) 다시 렌더링(re-render)하지 않는다. 즉, 레이아웃을 공유하는 경로에서 사용자가 형제 페이지 사이를 탐색할 때 레이아웃이 유지된다.

부분 렌더링이 없었다면 탐색할 때마다 전체 페이지가 서버에서 다시 렌더링 되었을것이다. 업데이트 중인 세그먼트만 렌더링하면 전송되는 데이터의 양과 실행 시간이 줄어들어 성능이 향상된다.


Advanced Routing Patterns

App Router는 고급 라우팅 패턴을 구현하는데 도움되는 patterns를 제공합니다.

  • Parallel Routes(병렬 경로): 독립적으로 탐색할 수 있는 두 개 이상의 페이지를 동일한 보기에 동시에 표시할 수 있습니다. sub-navigation이 있는 분할 보기에 사용할 수 있ㄴ다.(예: 대시보드.)
  • Intercepting Routes(경로 가로채기): 경로를 가로채서 다른 경로의 컨텍스트에 표시할 수 있다. 현재 페이지의 컨텍스트를 유지하는 것이 중요한 경우에 사용할 수 있습니다. 예를 들어, 하나의 작업을 편집하는 동안 모든 작업을 보거나 피드에서 사진을 확장하는 경우입니다.

Reference


avatar
snyungSoftware Engineer(from. 2018)
social-mailsocial-githubsocial-facebooksocial-book