제가 처음 Next.js 13을 사용할때만 되더라도 대부분 아직 13버전을 이용하지 않을때였는데 요즘은 대부분 13으로 시작을 많이 하시더라고요.
그래서 Next.js 13의 App Router
를 이용했을때 알아야 할것, 알면 좋은 것들에 대해서 정리해볼까 합니다. (App Router가 아니더라도 Pages 에서도 유용할것 입니다.)
일단 먼저 왜 App Router
를 쓰시는지 다시 생각해보세요. App Router
에 익숙하지 않다면 서버 컴포넌트와 클라이언트 컴포넌트때문에 생산성이 저하된답니다. 그래서 빠르게 제품을 만들어야 될 경우에는 개발속도에 발을 잡을 수 있죠.
또한 서버 컴포넌트의 존재로 Pages Router
보다 많은 메모리를 사용하게 됩니다.
그래서 App Router
를 사용할때는 서버 컴포넌트의 장점인 컴포넌트 별로 다른 렌더링 전략
을 가져가야만 하거나 App Router를 충분히 사용해본 경우
에 사용하는것을 추천합니다.
Next.js13 극한의 성능 최적화 예전에 이 글에서도 한번 다뤘던 내용입니다.
Next.js에서는 Image
컴포넌트가 존재하는데요. 굉장히 매력적인 기능이 많은 컴포넌트입니다.
하지만 그렇게 많은 기능이 있을수록 Next.js
의 서버에서 해주는 일이라는것을 잊지 마세요. 사이트에 이미지가 많은 경우 유저가 한번 들어올때 그 많은 이미지들이 최적화하는 과정을 Next.js
서버에서 해주고 있는것입니다.
서버컴포넌트 + 상황에 따른 route handler
여기에 이미지 최적화까지 하나의 서버에서 하면 Next.js
서버가 터지는건 일순간이겠죠.
페이지에 이미지가 거의 없거나 사용자가 그렇게 크지 않을것 같은 사이드 프로젝트정도에는 이용하셔도 괜찮습니다.
하지만 실제 운영에서 이용하실때는 cdn
을 이용하여 이미지를 최적화하는것을 추천드립니다.
이와 유사하게 Next.js내부에서 Optimizing을 해주는것은 그냥 아무비용없이 해주는것이 아닐겁니다. 수시로 모니터링을 하고 메모리 이슈가 있다면 한번 Optimizing부분을 의심해보세요.
13.5 버전 업데이트
최근에 Next.js 13.5
버전이 나온것을 알고 계신가요? App router
의 고질적인 문제인 메모리 이슈
를 잡아낸것을 확인할 수 있습니다.
실제로 13.5
를 적용한뒤 AWS의 메모리 사용량이 50프로 가까이 줄어들은것을 확인할 수 있었습니다.
이외에도 기존 13.3까지는 컴포넌트 별 isr
이 잘 동작하지 않았었는데 그 문제도 13.4
에서 고쳐졌더라고요.
이와같이 App router
는 아직 많은 개선이 이뤄지고 있습니다. 무려 438개의 개선을 이뤄냈다고 하네요. (13.4 -> 13.5)
그래서 다른 라이브러리들은 안정적으로 버전을 관리하는것을 추천하지만 App router
를 사용하실때는 주기적으로 버전 업데이트를 체크하신뒤 따라가시는것을 추천드립니다.
sass | vanilla-extract |
---|---|
App Router
를 선택한 순간 style framework에도 제약이 생깁니다.
물론 서버 컴포넌트를 fetch
만 하고 client에 props만 넘기는 용도로만 사용하면 굳이 제약은 없을것 같지만요.
일단 서버 컴포넌트에 css를 입히려면 빌드타임에 css를 생성해야합니다. 그래서 기존에 이용하던 대부분의 css-in-js
를 사용하기에는 어려울것입니다.
https://nextjs.org/docs/app/building-your-application/styling/css-in-js
그래서 zero-runtime
라이브러리인 vanilla-extract
, panda-css
등을 이용해야만 할것입니다. 하지만 이 라이브러리들도 완벽하게 서버 컴포넌트를 지원해줄지는 의문이죠.
vanilla-extract도 얼마전까지 서버 컴포넌트에서 이용하는것에 관련해서 이슈가 있었고, 서버 컴포넌트의 업데이트등에 의해 충분히 되던 코드가 안될 수 있기 때문입니다.
저는 그래서 sass
와 css module
을 이용하는것을 추천하는 편입니다.
classnames
라이브러리와 함께 사용하면 css-in-js의 생산성에는 못미쳐도 나쁘지 않은 생산성이 나오기때문에 충분히 이용할만한것 같습니다.
App router
를 선택하셨다면 대부분 이 이유라고 생각됩니다. 사실 서버컴포넌트의 zero-bundle
은 그렇게 크지 않은것 같습니다. 서버 컴포넌트는 data fetch의 용도로만 이용하고 실제로는 client component
로 도배를 할 수 밖에 없기 때문이죠.
그렇다면 어떻게 렌더링 전략을 채택하면 될까요?
사실 이것은 너무 당연하게 얘기되는 자주 변하면 SSR
, 아니면 SSG, ISR
이렇게 사용을 하면 됩니다. 하지만 조금 더 상세하게 알아보도록 하죠.
일단 ISR
을 최우선 선택으로 생각해보세요. 이 데이터는 ISR에 이용할 수 있을것인가?를 먼저 생각해보시면 됩니다. 예를 들어 어드민에서 받아오는 값이 있다고 가정해보겠습니다.
이런 경우에는 어드민이 업데이트 될시에만 데이터가 변경되기때문에 On-demand revalidation
을 이용하면 어드민이 변경될때만 그 컴포넌트는 fetch를 하기때문에 불필요한 fetch를 하지 않아도 됩니다.
추가적으로 블로그나 프론트 하드코딩으로 되어있는 컴포넌트가 아니면
SSG
를 쓸수있는 경우는 많이 없을겁니다.
SSR
은 사용자가 fetch할때마다 서버에서 fetch를 하고 server component를 렌더하기 때문이죠. 이는 역시 Next.js
의 메모리 이슈에 연계됩니다. 하지만 사실 정적인 데이터
거나, 어드민 데이터
가 아니라면 SSR로 사용할 수 밖에 없습니다. 단지 ISR
이 되는지 생각을 해보고 이용하셨으면 합니다.
App router
로 개발을 할때 가장 중요한 요소중 하나라고 생각됩니다.
서버 컴포넌트에서 fetch를 할때는 크롬 개발자 도구의 네트워크
, 콘솔
탭에 아무런 정보가 남지 않습니다. 사실 당연한거죠. 서버 컴포넌트는 서버니까요.
로컬에서 개발을 할 경우에는 터미널에 console.log가 보이기 때문에 큰 불편함이 없지만 이제 운영에 올라간 경우에는 브라우저에서 아무런 디버깅을 할 수 없습니다.
이것을 위해서는 프론트에서도 백엔드처럼 로깅작업이 필요합니다.
/var/log
폴더에 떨어트리면 됩니다.이 작업과 함께 client의 에러 로그를 위해 Sentry
를 함께 설정하면 모든 로그를 대체할 수 있습니다.
다음과 같이 설정을 하면 Next.js 13을 시작할때 심신의 안정을 가져올 수 있습니다..👻
이 글을 시작으로 Next.js 13 관련 게시물들을 작성할 예정입니다. 많은 관심 부탁드립니당.🎉
좋은 글 잘 읽고갑니다.