일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 렌더링
- 렌더링 동작원리
- 배칭
- mapped types
- 고급타입
- 상태 끌어올리기
- React
- 타스
- useMemo
- useCallback
- react code splitting
- react router dom v6
- Interface
- TS
- Front-End
- react rendering
- TypeScript
- Next.js
- 프론트엔드
- 타입스크립트
- 자동 배칭
- 자바스크립트
- 리액트
- rendering
- state 최적화
- router dom
- lifting state up
- NextJS
- JavaScript
- 리액트 코드분할
- Today
- Total
서녕이네 개발단지
[Next.js] Next.js 13 업데이트 내용 본문
Next.js 13이 2022년 10월에 컨퍼런스에서 다시 발표됐다고 한다. (디렉토리 구조, getServerSideProps 등 Next 정체성이 대거 바뀜)
Next 개발팀은 13버전 업을 통해 좀 더 제한없이 동적으로 동작하는 기반을 마련하고자 했다는 게 주요 컨셉이다.
🖐🏻 주요 변경사항
- app/Directory(beta) : 쉽고, 빠르고, 적은 클라이언트 JS
- Layouts(레이아웃)
- React Server Components (리액트 서버 컴포넌트)
- Streaming (스트리밍)
- Data Fetching
- Turbopack(alpha) : Rust 기반. Webpack 보다 700배, Vite보다 10배 빠른 번들러
- 새로운 next/image(stable) : 더 빨라진 Lazy Loading
- 새로운 @next/font(beta) : 구글 폰트 자체 내장
- 향상된 next/link(stable) : <a> 태그를 자식 요소로 넣을 필요 없음
Next.js 13 변경사항
☝🏻 위의 주요 변경사항에 대해 자세히 알아보자.
app/Directory : 새로운 디렉토리 구조 - beta
- 기존 Next에선 pages/ 디렉토리 내에 폴더, 파일을 생성하여 라우팅을 설정할 수 있었다.
👍🏻 이 형식이 우리에게 좋은 이유가, 우리가 react-router-dom 같은 것을 따로 쓰면서 별도 라우팅 코드를 세팅하지 않아도, 그냥 그 디렉토리 하위로 파일을 생성하면 그 파일이 그대로 라우팅 세팅이 되기 때문이다.
Next.js 13부터는 app/ 이라는 새로운 디렉토리로 라우팅을 설정할 수 있으며,
라우팅 환경개선뿐만 아니라 레이아웃, 서버 컴포넌트, 스트리밍, 데이터 패칭까지도 지원하는 형태로 향상시켰다.
그러면 이러한 app 디렉토리에서 우리가 무엇을 할 수가 있을까?
아래에서 계속 확인해 보자.
Layouts(레이아웃)
- 공통적인 UI를 children을 감싸는 랩핑 컴포넌트 형태로 쉽게 제공하는 형태이다.
이를 통해, 공통 레이아웃의 상태를 유지하고, 불필요한 리렌더링을 방지하며, 컴포넌트 간 상호작용을 향상시켰다.
💡 쉽게 말해, 원래 페이지 별 혹은 컴포넌트가 사라졌다가 다시 나타나는 등 컴포넌트 변경이 있으면 리렌더링을 시도하는데, Layouts을 쓰게 되면 이러한 컴포넌트 변경이 있어도 최대한 렌더링 된 상태를 유지하여 리렌더링으로 인한 성능 감소를 줄일 수 있다.
전체적인 콘텐츠 영역은 {children}를 통해서 배치하며, 동일한 라우팅 경로 내에서 일어나는 컴포넌트 변경 부분은 컴포넌트가 바뀌어도 최대한 렌더링이 일어나지 않고 유지되는 식이다.
❗️따라서 페이지 단위로 화면 내 컴포넌트가 수시로 바뀌어도 Layout 내에서는 리렌더링 비용을 최대한 줄여 성능을 향상시킬 수 있게 된다.
React Server Components (리액트 서버 컴포넌트)
- next 13에서는 Server Component 아키텍처를 지원한다.
Server Components를 사용하면, 클라이언트로 보내는 JS 코드량을 줄일 수 있어 빠르게 페이지 로딩이 가능하다고 설명한다.
또한, route가 로드되면 Next.js와 React 런타임이 각각 로드된다. (런타임이 로드될 때, 캐시가 가능하고 사이즈를 예측할 수 있어서, 애플리케이션이 점차 커져도 런타임이 증가하지 않는다❌고 한다.)
추가로 런타임이 async 하게 로딩되고, 서버로부터 Hydration 된 HTML이 클라이언트 쪽으로 점진적으로 향상되도록 제공된다고 한다.
Streaming (스트리밍)
- streaming은 app/ 디렉토리 내에서 이루어지는 기능인데, 서버 사이드 단에서 컴포넌트를 점진적으로 렌더링 한 뒤 스트리밍 방식으로 클라이언트에게 전달하는 방식이다.
기존에는 서버 사이드 렌더링을 할 때, 화면에 보여줄 데이터들을 백엔드 API를 통해 fetch를 해서 가져올 때까지 기다려야 했는데,
👉🏻 이러한 문제를 Streaming을 통해 해결할 수 있다.
고정적인 레이아웃 부분은 data fetch가 필요 없기 때문에 먼저 렌더링 한 뒤 클라이언트로 보낼 수 있고, 이후 다른 부분은 data fetch가 끝나면 그 이후에 별도로 렌더링을 한 뒤 클라이언트 단으로 보내주게 된다.
추가로 data fetch가 필요로 한 부분은 가져오기 전까지는 알아서 로딩 상태로 표시가 된다.

Data Fetching
- 이번에 app/ 에서 React Suspense 기반으로 구현된 새로운 data fetch 하는 방식이다.
- fetch() Web API를 사용할 수 있게 되면서, 이제는 컴포넌트 레벨에서도 SSR의 적용이 가능하다.
기존에는 getStaticProps와 getServerSideProps 함수를 별도로 export 하면서 서버 사이드 단에서 돌아가는 로직을 구현을 했다면, 이제는 별도로 함수로 export 하지 않고도 서버 사이드 로직을 구현할 수 있다.
- Next.js 컴포넌트들은 기본적으로 서버 컴포넌트이므로, 서버단에서 데이터를 불러온다.
- 데이터는 병렬적으로 일어난다. (각각의 패칭이 비동기 chaining으로 일어나지 않음)
- 데이터 패치는 자동으로 중복제거(deduping) 된다. 부모-자식 간의 동일한 요청들은 1회로 실행한다.
- Loading UI(혹은 Suspense), Streaming 등을 통해 데이터를 불러오는 영역과 미리 보여주는 영역을 나누어서 표현한다.
👇🏻 react에서 제공하는 use hook을 통해 아래처럼 구현하면 된다.
// app/page.js
import { use } from 'react';
async function getData() {
const res = await fetch('...');
const name: string = await res.json();
return name;
}
export default function Page() {
const name = use(getData());
return '...';
}
React는 fetch() API의 중복제거를 제공하며, Next.js는 캐싱과 재요청 처리까지 지원하려고 한다.
이를 통해, 기존의 SSG, SSR, ISR(Incremental Static Regeneration) 등의 기법을 아래와 같은 fetch() 옵션으로 대체 가능하다.
👉🏻 이러한 이점을 fetch API를 통해 이점을 활용할 수 있다.
fetch(URL, { cache: 'force-cache' });
fetch(URL, { cache: 'no-store' });
fetch(URL, { next: { revalidate: 10 } });
Turbopack(alpha)
- Rust 기반의 새로운 번들러다.
기존에 프론트엔드계에서 거의 필수 모듈인 webpack임에도 자바스크립트 기반의 툴로써 한계에 다다르게 되었다고 말하며, 이러한 한계를 대체할 Rust 기반의 번들러인 Turbopack을 소개한다.
❗️ Next.js 12부터 Rust 기반 툴링으로 전환했고, 현재는 더 빠른 트렌스파일링과 번들링 성능을 보여주고 있다.

- Webpack 보다 700배 빠른 업데이트
- Vite 보다 10배 빠른 업데이트
- Webpack 보다 4배 빠른 cold start(Single Page 표현을 위해 로컬에 데이터를 불러오고 HTML 기반으로 로드준비가 된 상태)
Turbopack은 Server Components, TypeScript, JSX, CSS 등 웹 개발에 필요한 주요 문법들을 지원한다.
또한, Turbopack은 개발에 필요한 최소한의 어셋만 번들링 하여 시작 시간이 매우 빠르다. (Vite와 유사함)
Turbopack에 여러 가지 기능들이 있는데, 아직 Alpha 버전이어서 아직은 많은 지원이 되지 않는 상태이다.
🖐🏻 우선 next 13 버전에서 "next dev --turbo" 명령어를 통해서 바로 turbopack을 통해 서비스를 돌려볼 수 있다.
새로운 next/image(stable)
- Next.js 13은 기존의 Image 컴포넌트에 좀 더 강력한 기능들을 부가해서,
layout 변경 없이 간단히 이미지를 표시하고 파일을 최적화하여 성능을 향상시켰다.
- 클라이언트 측에서 더 적은 양의 Javascript 코드를 가짐
- 더 쉽게 스타일링과 설정이 가능
- alt 속성을 필수로 제한하여 웹 접근성 향상
- 웹 플랫폼에 맞게 조정 (사이즈와 화질 등) - 이미지 로드가 느리면 기존 레이아웃이 밀리는 Layout Shift를 방지 (width, height 필수)
- hydration을 필요로 하지 않는 네이티브 lazy-loading으로 속도 향상
Next.js 13의 next/image 컴포넌트로 업그레이드
- 예전 버전의 이미지 컴포넌트는 'next/legacy/image'로 변경이 되면서, 이전에 사용하던 next/image 컴포넌트들을
➡️ 'next/legacy/image'로 자동으로 변경해 주는 codemod를 제공한다고 한다.
👇🏻 아래는 codemod 사용법이다.
// ./pages 디렉토리에 있는 코드들을 변경 시
$ npx @next/codemod next-image-to-legacy-image ./pages
새로운 @next/font(beta)
- next 13에서는 새로운 글꼴 시스템을 제공한다. 무엇보다 구글 폰트를 내장함!
- 커스텀 폰트를 포함하여 폰트를 자동으로 최적화
- 개인 정보 보호 및 성능 향상을 위한 외부 네트워크 요청 제거
- 모든 폰트 파일에 대한 내장형 자동 자체 호스팅 제공
- CSS size-adjust 속성을 적용하여 자동으로 레이아웃 이동이 발생하지 않음
이와 같이 새로운 폰트 시스템을 통해 성능 개선과 개인 정보를 보호하며 모든 Google 폰트를 편하게 관리할 수 있다.
CSS 및 폰트 파일은 빌드 시간에 다운로드되고 나머지 정적 asset과 함께 self-hosting 된다. (브라우저에서 Google로 요청 필요 없음)
❗️따라서 더 이상 폰트 사용을 위해 브라우저에서 Google로 폰트 요청을 하지 않아도 된다!
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}>
// 폰트 설정추가
import { Roboto } from '@next/font/google'
const roboto = Roboto({
weight: '300',
subsets: ['latin'],
})
export default function MyApp({ Component, pageProps }) {
return (
<main className={roboto.className}>
<Component {...pageProps} />
</main>
)
}
- 커스텀 폰트들도 자동 self-hosting, 캐싱, pre-loading 등이 제공된다.
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}>
전역 설정
- next.config.js 설정파일에 폰트에 관한 설정을 전역으로 설정할 수 있다.
// 전역 폰트옵션 설정
module.exports = {
experimental: {
fontLoaders: [
{ loader: '@next/font/google', options: { subsets: ['latin'] } },
],
},
}
향상된 next/link(stable)
- 기존에 next 12 버전까지는 next/link를 쓰기 위해서는 <a> 태그를 꼭 중첩시켜야 했다.
// Next.js 12 버전
import Link from 'next/link'
<Link href="/about">
<a>About</a>
</Link>
🙌🏻 하지만 이번에 next 13부터는 <a> 태그를 제외하고 사용할 수 있다!
// Next.js 13버전
import Link from 'next/link'
<Link href="/about">
About
</Link>
Next.js 13의 next/link로 업데이트
- Link 태그 역시 기존코드를 Next.js 13으로 업데이트하는 커멘드를 제공한다. 이를 root에서 실행하면, ./pages 경로에 반영해 준다.
npx @next/codemod new-link ./pages
기존 사용하던 형태
- 기존엔 Styled-Components, SEO 등을 적용하기 위해
a태그를 내부에 넣고 passHref로 링크를 전달해야 하는 번거로움이 존재했다.
import Link from 'next/link'
import styled from 'styled-components'
// This creates a custom component that wraps an <a> tag
const RedLink = styled.a`
color: red;
`
function NavLink({ href, name }) {
return (
<Link href={href} passHref legacyBehavior>
<RedLink>{name}</RedLink>
</Link>
)
}
export default NavLink
OG 이미지 생성
👇🏻 아래 예시를 보면 카카오톡이나 블로그 링크를 첨부하면 연관 이미지가 뜨는데, 이를 OG(Open Graph) Image라고 한다.
이는, 콘텐츠 클릭률을 높이기에(최대 40%) 많이 사용되지만, 정적 소셜카드는 시간 소비, 에러 이슈 등 유지보수가 까다로워 스킵되곤 한다.

https://seonzzi-honey-factory.tistory.com/49
[Next.js] NextJS란?
NextJS란? - Next.js는 리액트로 만드는 서버사이드 렌더링(SSR) 프레임워크다. - Next.js는 리액트를 위해 만든 오픈소스 자바스크립트 웹 프레임워크로, 리액트에 없는 서버 사이드 렌더링(SSR), 정적
seonzzi-honey-factory.tistory.com
🖐🏻 그러나 Next.js 13에서는 이를 개선한 동적 소셜카드 생성 라이브러리인 @vercel/og 를 도입했다고 한다.
// pages/api/og.jsx
import { ImageResponse } from '@vercel/og';
export const config = {
runtime: 'experimental-edge',
};
export default function () {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
}}
>
Hello, World!
</div>
),
);
}
❗️ 이는 기존 솔루션보다 5배 더 빠른 성능을 보여준다.
👉🏻 Vercel Edge Functions, WebAssembly 및 HTML, CSS를 이미지로 변환하고, React 컴포넌트 추상화를 활용하기 위한 새로운 핵심 라이브러리를 사용
미들웨어 API 수정
- 이전 Next.js 12에서 라우터와 유연성을 위해 미들웨어를 도입했다면, Next.js 13에선 기존에 도입된 미들웨어에서 일부 수정이 생겼다.
Request Header를 쉽게 설정
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Clone the request headers and set a new header `x-version`
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-version', '13');
// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
});
// Set a new response header `x-version`
response.headers.set('x-version', '13');
return response;
}
rewrite, redirect 없이 미들웨어에서 직접 리스폰스 제공
- 또한, Auth 인증 실패 등으로 리다이렉트가 필요할 때, 더 이상 rewrite, redirect를 쓰지 않고, 바로 response 선언 부분에서 Json 형태로 Response를 처리할 수 있다.
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';
// Limit the middleware to paths starting with `/api/`
export const config = {
matcher: '/api/:function*',
};
export function middleware(request: NextRequest) {
// Call our authentication function to check the request
if (!isAuthenticated(request)) {
// Respond with JSON indicating an error message
return NextResponse.json(
{
success: false,
message: 'Auth failed',
},
{
status: 401,
},
);
}
}
단❗️ 이는 next.config.js 설정파일에서, experimental > allowMiddlewareResponseBody 설정이 필요하다.
// next.config.js
const nextConfig = {
...
experimental: {
allowMiddlewareResponseBody: true
},
};
주요 변경사항
- 최소 요구 React 버전이 17.0.2 ► 18.2.0으로 상향
- 12.X 버전 지원이 종료되며, 최소 요구 Node.js 버전이 12.22.0 ► 14.6.0 상향
- swcMinify 설정 기본값이 false ▶︎ true 변경
- next/image ► next/legacy/image, next/future/image ► next/image 마이그레이션
- next/link가 <a> 태그를 자식으로 가질 수 없음. legacyBehavior 옵션으로 기존코드를 유지할 수 있으나, 커멘드로 업데이트 권장
- User-Agent 가 봇이면 더 이상 경로들을 prefetch 하지 않음
- 지원 종료된 target 옵션(MiddlewareInServerlessTarget)이 next.config.js 에서 제거
- 지원 브라우저가 변경 : Chrome 64+, Edge 79+, Firefox 67+, Opera 51+, Safari 12+, IE(지원종료)
참고
https://helloinyong.tistory.com/345
https://abangpa1ace.tistory.com/279
https://nextjs.org/docs/app/building-your-application/routing
'프론트엔드 > NextJS' 카테고리의 다른 글
[Next.js] NextJS란? (0) | 2023.10.23 |
---|