-
[Next.js] Next.js 13 StudyDev 2023. 4. 17. 11:10
* 표시는 이해한 내용을 정리한 것
Next.js 13 업데이트 사항
next.js blog에서 아래와 같은 기능들을 13 버전에 업데이트되었다고 소개하고 있습니다.
해당 기능들을 순차적으로 살펴보고자 합니다.
- app Directory (beta): Easier, faster, less client JS.
- Turbopack (alpha): Up to 700x faster Rust-based Webpack replacement.
- New next/image: Faster with native browser lazy loading.
- New @next/font (beta): Automatic self-hosted fonts with zero layout shift.
- Improved next/link: Simplified API with automatic <a>.
New app Directory (Beta)
Next 13 버전에서는 라우팅 및 레이아웃 개선을 위한 새로운 디렉터리인 app 디렉터리가 추가되었습니다.
그러나 아직 app 디렉터리는 베타 버전이기 때문에 프로덕션 환경에서 사용하지 않는 것이 좋습니다.
app 디렉터리를 생성할지 여부는 선택 사항입니다.
여전히 pages 디렉터리를 사용할 수 있으며, 이는 당분간 지원될 예정입니다. 또한 13 버전에서는 개선된 next/image와 next/link를 pages 디렉터리에서도 사용할 수 있습니다.
app 디렉터리에서는 다음과 같은 기능이 지원됩니다:
- Layouts
app 디렉터리를 사용하면 페이지 이동 전반에 걸쳐 상태를 유지하고, 비용이 많이 드는 재렌더링을 피하며, 고급 라우팅 패턴을 활성화하는 복잡한 인터페이스를 쉽게 레이아웃할 수 있습니다. 또한 레이아웃을 중첩하고 컴포넌트, 테스트 및 스타일과 같은 애플리케이션 코드를 경로와 함께 배치할 수 있습니다.
// app/blog/layout.js export default function BlogLayout({ children }) { return <section>{children}</section>; }
위와 코드와 같이 레이아웃을 컴포넌트를 작성할 수 있습니다. 레이아웃은 여러 페이지 간에 UI를 공유합니다. 페이지 이동 시 레이아웃은 상태를 보존하고 계속 인터렉션이 가능하며 다시 렌더링 하지 않습니다.
* 공통 UI를 쉽게 보여주는 것에서 더 나아가 상태를 유지하며, 계속 인터렉션이 가능하고 리렌더링 하지 않아 개발자 경험이 좋고, UX에 좋고, 효율적이다.
- Server Components
app 디렉터리는 React의 새로운 서버 컴포넌트 아키텍처에 대한 지원을 도입합니다. 서버 컴포넌트와 클라이언트 컴포넌트는 각각 서버와 클라이언트가 가장 잘할 수 있는 부분을 사용하므로, 훌륭한 개발자 경험을 제공하는 단일 프로그래밍 모델로 빠르고 인터랙티브 한 앱을 구축할 수 있습니다.
서버 컴포넌트를 사용하면 복잡한 인터페이스를 구축하는 동시에 클라이언트로 전송되는 자바스크립트의 양을 줄여 초기 페이지 로딩 속도를 높일 수 있는 기반을 마련할 수 있습니다.
경로가 로드되면 캐싱이 가능하고 크기를 예측할 수 있는 Next.js 및 React 런타임이 로드됩니다. 이 런타임은 애플리케이션이 커져도 크기가 증가하지 않습니다. 또한 런타임은 비동기적으로 로드되므로 서버의 HTML이 클라이언트에서 점진적으로 향상될 수 있습니다.- Streaming
app 디렉터리에는 UI의 렌더링 된 단위를 점진적으로 렌더링 하고 클라이언트에 점진적으로 스트리밍 하는 기능이 도입되었습니다.
Next.js의 서버 컴포넌트와 중첩 레이아웃을 사용하면 특별히 데이터가 필요하지 않은 페이지의 일부를 즉시 렌더링하고 데이터를 가져오는 페이지의 일부에 대해 로딩 상태를 표시할 수 있습니다. 이 접근 방식을 사용하면 사용자가 페이지 전체가 로드될 때까지 기다렸다가 페이지와 상호 작용을 시작할 필요가 없습니다.* UI를 통으로 로딩하여 보여주는 것이 아닌 분리하여 빨리 보여줄 수 있는 애들부터 보여주어 UX를 향상한다.
- Support for Data Fetching
// app/page.js async function getData() { const res = await fetch('https://api.example.com/...'); // The return value is *not* serialized // You can return Date, Map, Set, etc. return res.json(); } // This is an async Server Component export default async function Page() { const data = await getData(); return <main>{/* ... */}</main>; }
네이티브 불러오기 웹 API도 React와 Next.js에서 확장되었습니다. 가져오기 요청을 자동으로 중복 제거하고 컴포넌트 수준에서 데이터를 가져오기, 캐시 및 재검증하는 하나의 유연한 방법을 제공합니다. 즉, 이제 하나의 API를 통해 정적 사이트 생성(SSG), 서버 측 렌더링(SSR), 증분 정적 재생성(ISR)의 모든 이점을 사용할 수 있습니다.
// 이 요청은 수동으로 무효화될 때까지 캐시되어야 합니다. // `getStaticProps`와 유사합니다. // `force-cache`가 기본값이며 생략할 수 있습니다. fetch(URL, { cache: 'force-cache' }); // 이 요청은 모든 요청에서 리페치되어야 합니다. // `getServerSideProps`와 유사합니다. fetch(URL, { cache: 'no-store' }); // 이 요청은 10초의 수명으로 캐시되어야 합니다. // 재검증` 옵션이 있는 `getStaticProps`와 유사합니다. fetch(URL, { next: { revalidate: 10 } });
* 기존에는 staticProps, serverSideProps 등 api가 나누어져 있었다면 13 버전의 app 디렉터리 data fetching은 한 개의 api를 통해 같은 작업이 가능하다 가독성 또한 더 나아진 것으로 보인다.
Introducing Turbopack (Alpha)
Next.js 13에는 웹팩의 새로운 Rust 기반 후속 버전인 Turbopack이 포함되어 있습니다.
Webpack은 30억 회 이상 다운로드되었습니다.웹을 구축하는 데 필수적인 역할을 해왔지만, 자바스크립트 기반 툴링으로는 최대 성능의 한계에 도달했습니다.
Next.js 12에서는 네이티브 Rust 기반 툴링으로 전환하기 시작했습니다.먼저 바벨에서 마이그레이션 하여 17배 빠른 트랜슬레이션을 달성했습니다.
그런 다음 Terser로 교체하여 축소 속도가 6배 빨라졌습니다. 이제 번들링을 위해 네이티브에 올인할 때입니다.
터보팩 알파를 Next.js 13과 함께 사용하면 다음과 같은 결과를 얻을 수 있습니다:
웹팩보다 700배 빠른 업데이트
Vite보다 10배 빠른 업데이트
웹팩보다 4배 빠른 콜드 스타트터보팩은 개발에 필요한 최소한의 에셋만 번들로 제공하므로 시작 시간이 매우 빠릅니다. 3,000개의 모듈이 있는 애플리케이션에서 Turbopack은 부팅하는 데 1.8초가 걸립니다. Vite는 11.4초, Webpack은 16.5초가 소요됩니다.
터보팩은 서버 컴포넌트, 타입스크립트, JSX, CSS 등을 즉시 지원합니다. 알파 버전에서는 아직 많은 기능이 지원되지 않습니다. 로컬 반복 작업 속도를 높이기 위해 Turbopack을 사용해 본 여러분의 피드백을 듣고 싶습니다.* 터보팩이 기존의 vite나 웹팩보다 훨씬 빠르긴 하지만 새로운 기술이니만큼 어느 정도 레퍼런스가 쌓이면 사용하는 것이 좋을 듯하다.
next/image
Next.js 13에는 강력한 새 이미지 컴포넌트가 도입되어 레이아웃 쉬프트 현상 없이 이미지를 쉽게 표시하고 온디맨드 방식으로 파일을 최적화하여 성능을 향상할 수 있습니다.
Next.js 커뮤니티 설문조사에서 응답자의 70%가 프로덕션 환경에서 Next.js 이미지 컴포넌트를 사용했으며, 그 결과 핵심 웹 바이탈이 개선되었다고 답했습니다. Next.js 13에서는 next/image를 더욱 개선하고 있습니다.
새로운 이미지 컴포넌트는 아래와 같은 특성을 가진다.- 클라이언트 측 자바스크립트 코드 감소
- 더 쉬워진 스타일 지정
- 기본적으로 alt 태그를 필수 요소로 지정하여 접근성 향상
- 웹 플랫폼과 일치
- 네이티브 지연 로딩은 하이드레이션이 필요하지 않으므로 더 빠름
import Image from 'next/image'; import avatar from './lee.png'; function Home() { // 접근성 향상을 위해 이제 "alt"가 필수입니다. // 선택 사항: 이미지 파일을 앱/ 디렉터리 내에 배치할 수 있습니다. return <Image alt="leeerob" src={avatar} placeholder="blur" />; }
위와 같이 새로운 이미지 컴포넌트가 나옴에 따라
기존 이미지 컴포넌트의 이름이 next/legacy/image로 변경되었습니다. 기존 next/image 사용을 next/legacy/image로 자동 업데이트하는 codemod를 제공했습니다. 예를 들어, 이 명령은 루트에서 실행할 때./pages 디렉터리에서 codemod를 실행합니다.
npx @next/codemod next-image-to-legacy-image ./pages
* 기존의 next/image는 next/legacy/image가 되었으며, 새로운 next/image 컴포넌트를 소개하고 있다. 기존의 이미지 컴포넌트에서 불편했던 요소인 스타일 지정 및 접근성 향상을 위한 필수요소 등이 추가된 것으로 보인다.
next/font
Next.js 13에는 새로운 글꼴 시스템이 도입되었습니다:
- 사용자 정의 글꼴을 포함하여 글꼴을 자동으로 최적화합니다.
- 개인 정보 보호 및 성능 향상을 위해 외부 네트워크 요청을 제거합니다.
- 모든 글꼴 파일에 대한 자동 자체 호스팅 기능 내장
- CSS 크기 조정 속성을 사용하여 자동으로 레이아웃 쉬프트 제로화
이 새로운 글꼴 시스템을 사용하면 성능과 개인정보 보호를 염두에 두고 모든 Google 글꼴을 편리하게 사용할 수 있습니다. CSS 및 글꼴 파일은 빌드 시 다운로드되며 나머지 정적 에셋과 함께 자체 호스팅됩니다. 브라우저에서 Google에 요청을 보내지 않습니다.
import { Inter } from '@next/font/google'; const inter = Inter(); <html className={inter.className}>
자동 자체 호스팅, 캐싱 및 글꼴 파일 사전 로딩을 지원하는 등 사용자 정의 글꼴도 지원됩니다.
import localFont from '@next/font/local'; const myFont = localFont({ src: './my-font.woff2' }); <html className={myFont.className}>
글꼴 표시, 미리 로드, 폴백 등 글꼴 로딩 환경의 모든 부분을 사용자 정의할 수 있으며, 뛰어난 성능과 레이아웃 쉬프트 없음을 보장합니다.
* 새롭게 등장한 폰트 컴포넌트로 이미지 컴포넌트와 같이 최적화 및 레이아웃 쉬프트 방지에 뛰어나다고 소개하고 있다. 기존의 웹폰트 사용 시 클라이언트에서 요청하여 폰트를 보여주었다면, next 폰트 컴포넌트는 빌드 시 폰트를 다운로드하여 next 자체 호스팅을 사용 한한다. 따라서 실제 환경에서는 next 폰트 컴포넌트만을 이용하여 폰트를 지정했다면 브라우저에서 폰트 요청을 보내지 않게 된다.
next/link
next/link는 더 이상 하위 항목으로 <a>을 수동으로 추가할 필요가 없습니다.
이 기능은 12.2에서 실험적 옵션으로 추가되었으며 이제 기본값이 되었습니다.Next.js 13에서 <Link>는 항상 <a>를 렌더링 하며 기본 태그에 props을 전달할 수 있습니다.
예를 들어
import Link from 'next/link' // Next.js 12: `<a>`는 중첩되어야 하며 그렇지 않으면 제외됩니다. <Link href="/about"> <a>About</a> </Link> // Next.js 13: `<링크>`는 항상 `<a>`를 렌더링합니다. <Link href="/about"> About </Link>
* 기존의 Link 컴포넌트에서 불편했던 부분인 a tag를 직접 입력해야 했던 부분이 사라지고, 기본으로 Link 컴포넌트는 a tag를 렌더링 하도록 변경되었다.
OG Image Generation
오픈 그래프 이미지라고도 하는 소셜 카드는 콘텐츠 클릭 참여율을 크게 높일 수 있으며, 일부 실험에서는 전환율이 최대 40%까지 향상되는 것으로 나타났습니다.
정적 소셜 카드는 시간이 많이 걸리고 오류가 발생하기 쉬우며 유지 관리가 어렵습니다. 이 때문에 소셜 카드가 부족하거나 생략되는 경우가 많습니다. 지금까지는 개인화하여 즉석에서 계산해야 하는 동적 소셜 카드는 어렵고 비용이 많이 들었습니다.
트위터에서는 동적 소셜 카드를 생성하기 위해 Next.js와 원활하게 작동하는 새로운 라이브러리 @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> ), ); }
이 접근 방식은 HTML과 CSS를 이미지로 변환하고 React 컴포넌트 추상화를 활용하기 위한 새로운 핵심 라이브러리인 Vercel Edge 함수와 WebAssembly를 사용하여 기존 설루션보다 5배 더 빠릅니다.
* og image라고 하는 소셜 카드는 참여율, 전환율을 높이는 효과가 뛰어나지만 여러 가지 문제로 생략하거나 유지보수가 어려웠다. 이러한 부분을 해결하기 위해 트위터는 @vercel/og라고 하는 라이브러리를 만들었으며 해당 라이브러리로 동적 소셜 카드 생성 및 유지보수를 용이하게 만들었다.
Middleware API Updates
Next.js 12에서는 미들웨어를 도입하여 Next.js 라우터를 최대한 유연하게 사용할 수 있도록 했습니다.
초기 API 설계에 대한 피드백을 수렴하여 개발자 환경을 개선하고 강력한 새 기능을 추가하기 위해 몇 가지 추가 기능을 추가했습니다.
이제 요청에 헤더를 더 쉽게 설정할 수 있습니다:// 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; }
이제 다시 작성하거나 리디렉션 할 필요 없이 미들웨어에서 직접 응답을 제공할 수도 있습니다.
// 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 내에 실험적. allowMiddlewareResponseBody 구성 옵션이 필요합니다.
Breaking Changes
- 최소 필요한 React 버전이 17.0.2에서 18.2.0으로 상향되었습니다.
- 12.x가 지원 종료(PR)에 도달했기 때문에 최소 Node.js 버전이 12.22.0에서 14.6.0으로 상향되었습니다.
- swcMinify 구성 속성이 false에서 true로 변경되었습니다. 자세한 내용은 Next.js 컴파일러를 참조하세요.
- next/image import가 next/legacy/image로 이름이 변경되었습니다. next/future/image import가 next/image로 이름이 변경되었습니다. codemod를 사용하면 import 이름을 안전하게 자동으로 바꿀 수 있습니다.
- next/link 자식은 더 이상 <a>이 될 수 없습니다. 기존과 같이 사용하려면 legacyBehavior prop를 추가하거나 업그레이드하려면 <a>을 제거하세요. 코드를 자동으로 업그레이드하는 codemod를 사용할 수 있습니다.
- User-Agent가 봇인 경우 경로가 더 이상 프리페치되지 않습니다.
- 더 이상 사용되지 않는 next.config.js의 대상 옵션이 제거되었습니다.
- 지원되는 브라우저 중 Internet Explorer를 삭제하고 최신 브라우저를 대상으로 하도록 변경되었습니다. 여전히 브라우저 목록을 사용하여 타깃 브라우저를 변경할 수 있습니다.
- Chrome 64+
- Edge 79+
- Firefox 67+
- Opera 51+
- Safari 12+
Reference
https://nextjs.org/blog/next-13#introducing-turbopack-alpha
'Dev' 카테고리의 다른 글
[React] PIP 직접 구현해보기 (0) 2023.06.21 [HTML] youtube embed Cheat Sheet (0) 2023.04.17 [React] IntersectionObserver를 사용한 infinite scroll 구현하기 (0) 2023.04.17 [React] Swiper.js Cheat sheet (0) 2023.04.15 [Extension] mac에서 vs code 창 투명하게 하기 (0) 2023.04.15