스트리밍이 뭐양.. 점진적으로 데이터가 흐른다는건가...
Next.js의 서버 컴포넌트와 중첩 레이아웃을 사용하면 데이터가 특별히 필요하지 않은 페이지의 일부를 즉시 렌더할 수 있고, 데이터를 fetching하는 페이지의 일부에 loading state를 보여줄 수 있다. 이 접근방식으로 사용자는 전체적인 page와 상호작용 하기전에 전체 페이지가 로드될 때까지 기다릴 필요가 없다.
Vercel에 배포되면 app 디렉토리를 사용하는 Next.js 13 앱은 성능향상을 위해서 기본적으로 Node.js와 Edge runtimes 모두에서 응답을 stream 한다.
설명이 부족해! Beta 버전을 스윽 살펴볼까나.
Next.js는 앱에서 data를 fetch하는 새로운 방식을 제시한다. API가 React 및 웹 플랫폼에 맞게 간소화 되었다. 즉, app directory에서 getServerSideProps
, getStaticProps
, 그리고 getInitialProps
를 더이상 지원하지 않는다는 것을 의미한다.
대신! 컴포넌트 레벨에서 data를 fetch하고, cache하고, 재검증할 수 있는 방법이 있다.
여기서는 앱의 data 생명주기를 관리하는 fundamental concepts
와 best practice
에 대해서 설명한다. (두근두근)
app directory안에서, 직접적으로 데이터가 필요한 Server Components 내부에서 data를 fetching 하는것이 좋다.
Server Components는 항상 서버에서 data를 fetch한다.
Server Components내부에서 data를 fetching하는것은 다음과 같은 매우 많은 이점을 가진다.
이러한 새로운 모델에서는 여러 컴포넌트에서 같은 data를 요청하는 경우에도, 우리(Next.js)는 data를 props를 통해 다른 Server Components로 보내는 대신, 필요로 하는 Server Components 내부에서 직접 data를 fetching하는것을 추천한다.
background에서 React와 Next.js는 동일한 데이터를 두번 이상 가져오는것을 피하기 위해서 cache와 중복제거를 한다.
현재 클라이언트 컴포넌트에서는 fetch가 지원되지 않는다. 예를 들어 SWR과 같은 서드 라이브러리를 사용해서 fetch가 가능하지만, 이는 성능상의 이슈를 일으킬 수 있다. 가능하다면
use
를 사용하거나fetch
를 사용해서 Server Components 안에서 data fetching logic을 유지하고, data를 클라이언트 자식 컴포넌트로 내려주라고 하네요.
부모 레이아웃과 자식 간에 데이터를 전달할 수 없다. 그렇지만, 동일한 data를 route에서 한 번 이상 가져올 수 있고, React는 자동으로 성능에 영향을 주지 않고 요청을 중복제거한다.
app 디렉토리에서는 layout, pages, 그리고 components안에서 data를 fetch할 수 있다. 그러나 컴포넌트 레벨에서 data를 fetching 하는것은 어떻게 React 작업과 동시성을 가질지(?), 특히 Streaming과 Suspense와 호환되어야 한다.
새로운 data fetching 방식은 native Web API위에서 구축되며 Server Components내부에서 async/await
을 사용한다. Promises RFC는 슬쩍 넘어간다.
fetch()는 원격 리소스를 fetch하는데 사용되며 promise를 반환한다. React는 fetch를 확장해서 자동 요청 중복 제거를 제공하고, Next.js는 fetch의 옵션 객체를 확장해서 각 요청이 캐싱 및 재검증 규칙을 따를 수 있도록 했다.
React는 동일한 입력의 fetch 요청을 temporary cache에서 자동으로 cache한다. 이는 redering pass동안에 data가 두 번 이상 fetch되는 것을 방지하기 위한 최적화이며, 특히 여러 컴포넌트에서 같은 데이터를 가져와야 할 때 유용하다.
예를 들어, 중첩된 레이아웃에 걸쳐 있는 트리의 여러 컴포넌트 안에서 현재 사용자를 fetch할 수 있다. 이 최적화는 안전할 뿐만 아니라 사용되는 컴포넌트에서 데이터를 fetch하도록 권장한다.
fetch를 사용할 수 없는 경우에 React는 요청 동안에 데이터를 캐시할 수 있는 cache function을 제공한다.
Next.js에서는 Static과 Dynamic, 두 가지 타입의 데이터가 있다.
기본적으로 Next.js는 자동으로 static fetch를 수행한다.
예?
즉, 데이터는 build time에 불러와지고, cache 되며, 각각의 요청에 재사용된다. 개발자는 정적 데이터의 캐시 및 재검증 방식을 컨트롤 할 수 있다.
정적 데이터를 사용하는 것에는 두가지 이점이 있다.
1. 요청수를 최소화하여 데이터베이스의 부하를 줄일 수 있다.
2. 데이터는 로딩 성능 향상을 위해 자동으로 캐시된다.
그러나 최신 데이터를 가져고오 싶은 경우도 있다. Next.js는 요청을 동적으로 할 수 있게 지원한다. 즉, 데이터는 요청 때 불러와지고 캐시되지 않는다.
캐싱은 CDN과 같은 곳에 데이터를 저장화는 과정이기에 각 요청에 대해 원본 데이터로부터 다시 가져올 필요가 없다.
Next.js 캐시는 전역으로 퍼트릴 수(distribute) 있는 영구적인 HTTP 캐시이다. 즉, 캐시를 자동으로 확장할 수 있고, 플랫폼에 따라 여러 지역에서 공유 가능하다.
server rendering동안에 Next.js가 fetch를 발견하면 캐시를 확인하여 데이터가 사용 가능한지 확인한다. 사용 가능하다면, 캐시된 데이터를 return 하고, 그렇지 않으면 fetch 하고 데이터를 저장한다.
재검증은 캐시를 정리하고, 최신 데이터를 다시 가져오는 프로세스다. 이 기능은 당신의 데이터가 바뀌었을 떄 당신의 앱이 최신 버전을 보여줄 수 있도록 보장하고자 할 때 유용하다.
Next.js는 두가지의 재검증 타입을 제공한다.
on-demand 재검증은 미래에 더 추가될 것이다.
Streaming과 Suspense는 클라이언트에 UI의 단위(units of the UI)를 점진적으로 렌더링하고, 점진적으로 스트림 렌더링하는 새로운 React 기능이다.
Streaming and Suspense are new React features that allow you to progressively render and incrementally stream rendered units of the UI to the client.
Server Components와 중첩된 레이아웃에서 특별히 데이터가 필요하지 않은 페이지는 즉시 렌더되고, 데이터를 불러오는 일부 페이지에 대해 loading state를 보여줄 수 있다. 즉, 사용자는 페이지와 상호작용을 하기 전에 전체 페이지가 로드되기를 기다릴 필요가 없다.
Next.js는 두가지 데이터 패칭 패턴을 지원한다. (병렬과 순차)
요청들이 in a route에서 활발하게 시작되며 동시에 데이터를 로드한다. 이는 클라이언트 서버의 waterfalls를 감소하며 데이터를 로드하는 총 시간이 줄어든다.
in a route의 요청들이 서로에게 의존하며 waterfall 패턴으로 데이터를 로드한다. 하나의 fetch가 다른 결과물에 의존하거나, 다음 fetch이전에 자원을 절약하기 위해 조건을 충족하기를 원하는 경우가 있을 수 있다.(?) 그러나 순차적으로 데이터를 가져오는 것은 의도치 않게 로드 시간이 길어질 수 있다.
Streaming 파트 끗! 다시 Next.js 13으로!
Web API의 native fetch는 React와 Next.js에서 확장되었다. 컴포넌트 레벨에서 자동으로 fetch 요청을 중복 제거 하며, 캐싱하고, 재검증한다. 즉, SSG, SSR, ISR이 이제는 하나의 API로 쌉가능이다.
// 이 요청은 수동으로 무효화 될 때까지 캐시되어야 한다.
// getStaticProps와 비슷하다.
// 'force-cahe'는 기본값이며 생략 가능하다.
fetch(URL, { cache: 'force-cache' });
// 이 요청은 매 요청마다 refetch되어야 한다.
]// 'getServerSideProps'와 비슷하다.
fetch(URL, { cache: 'no-store' });
// 이 요청은 10초동안 캐시되어야 한다.
// 'revalide' 옵션이 있는 'getStaticProps'와 비슷하다.
fetch(URL, { next: { revalidate: 10 } });
app 디렉토리 안에서는 서버로부터의 streaming responses지원을 포함해서 layouts,pages그리고 components안에서 데이터를 불러올 수 있다.
Next.js는 웹팩의 새로운 Rust기반 후속작인 Turbopack을 포함한다.
웹팩은 30억번 이상 다운로드 되었다... 웹 구축에 필수적인 요소였지만, JS기반의 tooling으로 가능한 최대 성능의 한계에 봉착했다.
Next.js 12에서는 native Rust-powered tooling으로 전환하기 시작했다.
We started by migrating away from Babel, which resulted in 17x faster transpilation. Then, we replaced Terser, which resulted in 6x faster minification.
Turbopack alpha를 Next.js 13와 함께 사용하면]
다음과 같은 글이 이따...
진짜 Vite보다 10배 빠르다고?
Next.js의 Turbopack은 오직
next dev
만 지원한다.next build
에 대한 지원을 추가하기 위한 작업을 진행중이다.
Try out the Turbopack alpha today in Next.js 13 with next dev --turbo.
Nextjs는 성능을 향상시키기 위해 레이아웃 변경 없이 이미지를 쉽게 표시하고 온디맨드 방식으로 파일을 최적화는 강력한 새로운 이미지 컴포넌트다.
더욱 강력해진 이미지 컴포넌트를 소개한돠!
import Image from 'next/image';
import avatar from './lee.png';
function Home() {
// "alt" is now required for improved accessibility
// optional: image files can be colocated inside the app/ directory
return <Image alt="leeerob" src={avatar} placeholder="blur" />;
}
힝... 오래된 이미지 컴포넌트 next/legacy/image
로 변경되었다.
We've provided a codemod that will automatically update your existing usage of next/image to next/legacy/image. For example, this command would run the codemod on your ./pages directory when run from the root:
npx @next/codemod next-image-to-legacy-image ./pages
Next.js 13은 새로운 폰트 시스템을 도입해똬!
새로운 폰트 시스템을 사용하면 성능과 개인정보 보호를 염두에 두고 모든 Google Fonts를 사용할 수 있다.
CSS 및 폰트 파일은 build time에 다운로드 되고, 나머지 정적 assets들과 함께 self-hosted 된다. 브라우저에서 Google로 요청을 보내지 않는다.
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}>
self-hosting, 캐시, 폰트 파일 프리로딩을 포함한 custom fonts 또한 지원된다.
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}>
next/link에서 더이상 a 태그를 자식으로 추가할 필요가 없당. Next.12에서 실험 옵션이었고, 현재는 default다. Next.js 13에서 Link 태그는 항상 a를 렌더링한다.
To upgrade your links to Next.js 13, we've provided a codemod that will automatically update your codebase. For example, this command would run the codemod on your ./pages directory when run from the root:
npx @next/codemod new-link ./pages
내용 많당. 그리고 신기하다. 이 사람들은 무슨 생각을 가지고 살까. 오로지 Next.js에 진심이지 않을까
정리는 여기까지 하려고 한다.
이후에도 OG Image Generation 와 Middleware API Updates 내용이 있다. 물론 읽어봤지만 솔직히 잘 모르겠다. 미들웨어 같은경우는 12버전의 내용을 읽어봐야겠다. 히히
공식문서를 한땀한땀 읽어본건 정말이지... 거의 처음이라고 해도 과언이 아니다. 생각보다 힘들었고 생각보다 즐거웠다. (뭔소리지?) 공식문서에서도 반복적으로 강조하는 부분이 있다는 것을 알았고, 여러 표현들을 써가며 설명하려고 애쓴 흔적이 보였다.
사실 Next.js 13버전이 릴리즈 되기전에 React공식 문서를 한땀 한땀 읽어나가고 있었다. 그것도 읽으면서 한번 쭉 정리를 해 보고 있었는데 마침 얘가 나와서... 궁금증에 읽어본다는게 우선순위가 바뀌어 버렸...네요... 이제 얘는 다 정리했으니 다시 훑어보고(벌써 1편의 내용이 가물가물하다! 세상에!) React로 넘어가려고 한다.
사이드프로젝트의 13버전으로의 마이그레이션도 얘기가 나오고 있다.
할게 정말 많고 서류는 미친듯이 떨어지고 있다. 사실 이걸 정리하는것보다 이력서 손보고 프로젝트 리팩토링이 더 급한것도 사실이다. 지원도 계속 해야하고! 그래도 중간 중간 환기차 읽어보면서 정리한거니까... 이러한 습관이 나에게 큰 자산으로 남길 바란다.
읽기 싫어서 같이 읽기 스터디 하실래요? 하려고 했는데 까비!