웹 어플리케이션을 구축하기 위한 React 프레임워크
👇 그래서.. React랑 뭐가 다른건데!!
👇 React와의 차이를 알아보기 위해 CSR과 SSR에 대해 짚고 넘어가보자!
서버에서의 처리없이
클라이언트로 보내주기 때문에, 모든 JavaScript 파일을 다운로드하는 동안 제대로 된 화면을 볼 수 없다.렌더 가능한
상태로 서버에서 클라이언트로 전달되기 때문에, JavaScript 파일이 다운로드 되는 동안 사용자는 로딩 화면만 보고 있지 않아도 된다.React와 Next.js의 가장 큰 차이점 중 하나는 렌더링하는 방식에 있다.
React는 CSR, Next.js는 SSR 방식으로 렌더링한다.
반면, Next.js는 웹에 사이트를 요청했을 때 서버 측 렌더링을 거친 후 HTML과 JS를 따로 reponse한다.
💡 Next.js의 작동원리는 다음과 같다.
1. 초기에 사용자가 서버에 접속을 요청하면, SSR 방식으로 렌더링될 HTML을 보낸다.
2. 브라우저에서 JavaScript를 다운로드하고 React를 실행한다.
3. 사용자와 페이지가 서로 상호작용하며 다른 페이지로 이동하게 될 경우에는 CSR 방식으로 브라우저에서 처리한다.
pre-render(HTML을 JS 처리하기 전, 사전에 생성)
하기 때문에, 검색엔진 최적화가 가능해진다. Hydration
이라고 부른다.리액트 문법을 쓰는 프론트 문법을 쓸 수 있게 도와주 백엔드 프레임워크
라고 할 수 있다.다음은 공식 문서에서 가져온 Next.js 특징 중 일부이다.
- 직관적인 페이지 기반 라우팅 시스템
- 사전 렌더링, 정적 생성(SSG) 및 서버 측 렌더링(SSR)은 페이지 별로 지원
- 더 빠른 페이지 로드를 위한 자동 코드 분할
- 최적화된 프리패치를 사용한 클라이언트 측 라우팅(CSR)
- 내장 CSS 및 Sass 지원 및 모든 CSS-in-JS 라이브러리 지원
👇 좀 더 자세히 알아보자!
React와 달리, 별도의 세팅없이 페이지를 기반으로 한 라우팅을 지원한다. React에서는 별도의 라우터를 제공하지 않기 때문에, react-router-dom
이라는 패키지를 설치하여 사용했다.
Next.js 13은 app 폴더 하위에page
파일을 추가하고 그 안에 레이아웃을 넣는 방식으로, 추가한 파일을 export하게 되면 폴더명이 페이지 route가 되어 해당 파일이 라우터 역할을 하게 된다!
ex1. app/blog/page.js
→ /blog
ex2. app/blog/first-blog/page.js
→ /blog/first-blog
항상 미리 정의된 경로를 사용할 수 있는 것은 아니다. 예를 들어 블로그 게시물의 경로는 /blog1, /blog2, /blog3 … 과 같은데, 모든 경로를 미리 정의하거나 페이지 컴포넌트를 생성하는 일은 굉장히 비효율적이다.
이때 사용하는 것이 동적 라우팅
이다. [folderName]
과 같이 폴더 이름을 대괄호로 묶어주면 해당 페이지 컴포넌트가 동적으로 라우팅 된다.
클라이언트 사이드에서 동적 경로에 접근하고 싶다면 next/link
를 사용해주면 되고, router.push
같은 메소드를 사용할 수 도 있다!
app/category/[slug]/page.js
Next.js 13 Automatic Routing에 따라 app 폴더 하위에 category 폴더를 만들고, 그 안에 Dynamic Routes를 위한 [slug] 폴더를 만든 것이다.
/category/food
, /category/study
등의 주소는 모두 /post/[pid].js
로 매칭된다.
[id]나 [slug]처럼 동적인 부분은 Layout과 Page나 Head 컴포넌트들에게 params prop으로 전달된다.
/category/food
→ { slug: 'food' }
/category/study
→ { slug: 'study' }
app/shop/[...slug]/page.js
[slug]에 ...
을 추가하여 shop 하위의 모든 경로를 잡아낼 수 있다.
/shop/clothes
→ { slug: ['clothes'] }
/shop/clothes/pants
→ { slug: ['clothes', 'pants'] }
/shop/clothes/tops/t-shirts
→ { slug: ['clothes', 'tops', 't-shirts'] }
코드 분할은 다른 페이지에 대한 코드는 처음에 제공하지 않고, 원하는 페이지에 접근하는데 필요한 chunk(작은 코드 조각)만을 로드한다.
여러 개의 페이지가 있는 웹 사이트일지라도 필요한 페이지만을 빠르게 로드할 수 있으며, 이는 JavaScript 페이로드를 최소화하고 애플리케이션 로드 시간을 개선할 수 있다.
초기 페이지 로드에 필요하지 않은 구성 요소가 있는 경우 다음(👇)과 같이 동적으로 가져올 수 있다. 이는 필요할 때만 Puppy를 로드하도록 지시하고 있다.
// import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";
// ...
const Puppy = dynamic(import("../components/Puppy"));
<Link />
컴포넌트를 통한 페이지 이동이 빠르고 매끄럽다. HTML의 a 태그와 달리, 페이지를 리로딩하지 않는다. <Link />
가 뷰포트에 보이면 관련 페이지를 백그라운드에서 미리 가져오기 때문에, 사용자가 링크를 클릭했을 때 매우 빠르게 해당 페이지로 이동할 수 있게 해준다.
TypeScript를 활용하기 위해서 웹팩이나 바벨을 만지지 않아도 된다. TypeScript를 설치하고 yarn run dev를 해주면 자동으로 tsconfig, next-end.d.ts가 생성되어 TypeScript를 사용할 수 있다.
yarn add typescript @types/node @types/react
yarn run dev
초기 페이지 로딩에서는 SSR 방식을 이용하여 처리하고, 이후의 요청에 대해서는 CSR 방식으로 처리하기 때문에 SSR 방식의 장점(SEO에 유리)과 CSR의 이점을 모두 활용할 수 있다.
Next.js는 모든 페이지를 사전 렌더링한다.
app/
디렉토리가 등장하여 라우팅 및 레이아웃 기능을 개선
했다.export default function Loading() {
return(
<div>Loading...</div>
)
}
기존 버전에서는 데이터를 가져올 때 getServerSideProps()나 getStaticProps()를 사용했지만, Next.js 13 버전부터는 이 문법들을 사용하지 않는다.
공식문서에 따르면, 현재 Client Component에서의use()
사용은 권장되지 않으며, 이는 무수한 리렌더를 유발할 것이라고 언급하고 있다. Client Component에서 fetch 데이터가 필요하다면, SWR과 React Query와 같은 라이브러리 사용을 추천한다고 한다.
fetch('https://...'); // cache: 'force-cache' is the default
캐시된 데이터의 유효성
을 주기적으로 다시 검사하려면 next.revalidate
옵션을 사용해서 리소스의 캐시 유효시간(초)을 설정할 수 있다.fetch('https://...', { next: { revalidate: 10 } });
fetch('https://...', { cache: 'no-store' });
{ cache: '' }
를 넣어줄 수 있다. cache에 들어가는 내용에 따라 기존의 getServerSideProps(), getStaticProps()의 기능을 구현할 수 있다.
// Similar to `getStaticProps`.
fetch(URL, { cache: 'force-cache' });
// Similar to `getServerSideProps`.
fetch(URL, { cache: 'no-store' });
// Similar to `getStaticProps` with the `revalidate` option.
fetch(URL, { next: { revalidate: 10 } });
이 외에도 Next.js 13에서 변경된 부분이 다수 있다. 자세한 내용은 nextjs.org를 참고해보자!
📘참고자료
How Next.js Works
What is Next.js?
Next.js를 사용하면서 리액트랑 별반 다르지 않다고 느꼈던 이유
[Next.js] 기본 개념 : Next.js 란? Next.js를 왜 사용할까? Next.js의 장점은?
Next.js 13
Next.js 13 신버전 발표회 요약
Next.js의 Routing
Next.js Dynamic Import(동적 가져오기): 성능 및 사용자 경험 개선
dynamic-routes
Next.js 에 대한 깔끔한 정리 감사합니다!!
특히, Next.js를 프론트 문법을 쓸 수 있게 도와주는 백엔드 프레임워크라고 정리해주신 부분이 가장 와 닿았던 것 같아요.
Next.js는 자체적으로 백엔드 구현이 가능하고, 최근 공개된 Next13의 기능들을 살펴보았을 때 ‘풀스택 프레임워크’에 가까워지고 있다는 느낌이 강한 것 같아요.
특히 Nested Routing과 Dynamic Routing의 경우 Next를 사용하는 개발자의 경험을 크게 향상시켜주는 좋은 기능이라고 생각이 되네요! 최근에 Next 13에서 공개된 app/Directory 를 직접 사용해보았었는데, 사용성이 확연히 개선되었음을 알 수 있었어요!!
또한 최근 Next13에서 선보인 기술 중 React use 훅을 이용한 Data Fetching을 흥미롭게 보았었는데, 리렌더 관련 이슈가 해결된다면 추가적인 라이브러리에 의존하지 않아도 훌륭한 ㅡ론트엔드 메타 프레임워크로 자리매김할 수 있겠다는 생각이 들었어요!
좋은 글 감사합니다!! 수고하셨어요 :)
우와 넥제 항상 써보자는 이야기만 해보고 실제로 써본 적이 없었는데, 이렇게 개념 잘 설명해주셔서 감사합니다. 여러모로 넥스트 코드가 아직 익숙하지 않은 것들도 꽤 있는 듯 해요. 실습 열심히 복습해보겠습니다!!
잘 정리된 글 덕분에 NEXT.js와 SSR에 대한 기초지식을 확실히 알고가는 것 같아요!
SSR로 렌더하는 것이 CSR보다 속도적인 측면에서 얼마나 더 유리한가 를공부해보았는데 아무래도 첫 페이지 로딩은 SSR처럼 서버에서 프리패치를 한 후 데이터를 보내주기 때문에 SSR로 처리하는 것이 유리한 것 같네요. CSR과 SSR을 섞어쓰는 하나의 예시로는 헤더나 GNB푸터 등은 SSR로 구현해두고 컨텐츠부분만 CSR로 구현해두어서 사용하는 방법이 있다는 것도 새로 알았습니다!
사실 이 두가지의 방법을 선택하려면 어떤 기술이 얼마나 어느부분에서 뛰어난지를 고민해봐야하는데 크롬 개발자도구에 LightHouse라는 도구를 사용하면 FCP FMP 등의 지표등을 확인할 수 있으니 추후에 사용해볼 기회가 오면 좋겠습니다!
LightHouse에대한 아티클 - https://velog.io/@dell_mond/Lighthouse-%EC%82%AC%EC%9A%A9%EB%B2%95
CSR과 SSR의 속도 비교에 대해 - https://medium.com/wantedjobs/%EC%9B%B9-%EC%84%B1%EB%8A%A5-%EC%B5%9C%EC%A0%81%ED%99%94-ssr-cache-%EC%A0%81%EC%9A%A9%EA%B8%B0-bf022e3a1a72#:~:text=SSR%20%ED%8F%89%EA%B7%A0%EC%84%B1%EB%8A%A5%2059%EC%A0%90&text=LCP%20%EC%84%B1%EB%8A%A5%EC%9D%80%201%EC%B4%88,%EB%9E%9C%EB%8D%94%EB%A7%81%EC%9D%B4%20%EC%9E%98%20%EB%8F%99%EC%9E%91%ED%95%A9%EB%8B%88%EB%8B%A4.
와우 이해도 쉽고 간결하게 정말 잘 써주셨네요!
설명해주신 Next.js의 작동원리에 따르면, Next.js는 처음에 SSR 방식으로 초기 구동 속도를 줄이면서, 이후에는 CSR 방식으로 이후 구동 속도를 빠르게 해주므로 혼합된 방식을 사용하면서 렌더링 측면에서 정말 매력 있다는 생각이 드네요!
[...slug]처럼
...
으로 그 하위 모든 경로까지 잡아내는 것도 한번 더 상기하고 갑니다!dynamic에 대해서는 처음 알게 되었는데요, 필요시에 동적으로 가져올 수 있도록 쉽게 관리할 수 있는 좋은 기능인 것 같아요!! 이전에 성능 최적화를 할 때 사용한 lazy랑 비슷한 기능을 하는 것 같네용 잘 활용해야겠어요!
가 뷰포트에 보이면 관련 페이지를 백그라운드에서 미리 가져온다는 점도 처음 알았어요!! 이 동작 방식을 이해하고 나니까 왜 빠르게 이동할 수 있는지 확 와닿네요!!! ` loading.js`도 편히 사용할 수 있다는 점에서 너무 매력적이에요..!!흥미롭게 잘 읽었습니다!!