- Published on
Nextjs 10 릴리즈 및 적용 후기
- Author
- Name
- yceffort
nextjs 10.0.0이 릴리즈 되었다. 내가 좋아하는 오픈소스 중 하나 이기 때문에, 릴리즈 노트를 읽어보면서 당장 내 블로그에 적용해보았다. 그리고 적용하면서 어떤게 바뀌었는지 하나씩 확인해보려고 한다.
빌트인 이미지 컴포넌트, 그리고 자동 이미지 최적화
이미지는 마크업과 함께 웹에서 큰 트래픽을 유발하는 범인중 하나다. 이러한 이미지를 최적화 하기 위해, next/image
라는 전용 이미지 컴포넌트를 적용하였다. 브라우저에서 Webp
가 사용 가능하다면, 해당 이미지를 변환해서 적은 용량으로 내려주고, 동시에 lazy loading도 해준다고 한다.
대상 이미지
적용전
const AuthorPhoto = styled.image`
display: inline-block;
margin-bottom: 0;
border-radius: 50%;
background-clip: padding-box;
width: 75px;
height: 75px;
cursor: pointer;
`
return <AuthorPhoto alt={name} src={photo} />
<img
alt="yceffort"
src="/profile.png"
class="Author__AuthorPhoto-sc-1ywmx02-0 fMrwt"
/>
accept-ranges: bytes
access-control-allow-origin: *
age: 1331855
cache-control: public, max-age=0, must-revalidate
content-disposition: inline; filename="profile.png"
content-length: 30710
content-type: image/png
date: Wed, 28 Oct 2020 02:05:42 GMT
etag: W/"078a2ad86a1350e007d801e7f74b073ed415e5bdd60a60e5b65b9fafe972af03"
server: Vercel
status: 200
strict-transport-security: max-age=63072000w
x-content-type-options: nosniff
x-frame-options: DENY
x-vercel-cache: HIT
x-vercel-id: icn1::chhv4-1603850742953-91ba1434fc9c
x-xss-protection: 1; mode=block
적용후
그리고 이를 next/image
로 아래와 같이 바꿨다.
import Image from 'next/image'
const AuthorPhoto = styled(Image)`
display: inline-block;
margin-bottom: 0;
border-radius: 50%;
background-clip: padding-box;
width: 75px;
height: 75px;
cursor: pointer;
`
// width와 height를 지정해줘야 한다.
return <AuthorPhoto alt={name} src={photo} width={75} height={75} />
<img
alt="yceffort"
data-src="/_next/image?url=%2Fprofile.png&w=320&q=75"
data-srcset="/_next/image?url=%2Fprofile.png&w=320&q=75 320w"
class="Author__AuthorPhoto-sc-1ywmx02-0 fMrwt"
style="visibility: visible; height: 100%; left: 0px; position: absolute; top: 0px; width: 100%;"
src="/_next/image?url=%2Fprofile.png&w=320&q=75"
srcset="/_next/image?url=%2Fprofile.png&w=320&q=75 320w"
/>
accept-ranges: bytes
access-control-allow-origin: *
age: 276
cache-control: public, max-age=0, must-revalidate
content-disposition: inline; filename="profile.png"
content-length: 18898
content-type: image/webp
date: Wed, 28 Oct 2020 02:06:37 GMT
server: Vercel
status: 200
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-content-type-options: nosniff
x-frame-options: DENY
x-robots-tag: noindex
x-vercel-cache: HIT
x-vercel-id: icn1::q6js7-1603850797310-7e6bd3beb3f0
x-xss-protection: 1; mode=block
일단 이미지가 눈에 띄게 lazy loading이 되었고 (나중에 떴고) 이미지 사이즈도 webp를 사용하면서 눈에 띄게 줄어든 모습이다. 구글 크롬팀에서 이미지 성능을 향상 시킬 수 있는 리액트 컴포넌트를 만들 수 있도록 도와주었다고 하는데, 나중에 소스 코드를 보는 것도 재밌을 것 같다.
국제화 라우팅
당장 내가 쓸 일이 있을지는 모르겠지만, 언어별 라우팅을 지원한다. 그리고 최신 브라우저가 지원하는 Accept-language
헤더를 기반으로 언어 감지를 할 수 있는 기능도 추가되었다고 한다.
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'nl'],
domains: [
{
domain: 'example.com',
defaultLocale: 'en',
},
{
domain: 'example.nl',
defaultLocale: 'nl',
},
],
},
}
성능 분석
nextjs를 사용하는 웹 어플리케이션의 성능을 분석할 수 있는 도구를 지원한다.
당장은 vercel만 지원하는 것 같은데(?) 운좋게도(?) 블로그가 vercel로 서빙되고 있기 때문에 당장 시도해보러 갔다.
(점수가 깎이는 것은 아마도 메인페이지의 페이지 전환 버튼 때문인 것 같다. 현재 타이틀 제목 길이에 따라서 페이징 버튼이 위아래로 일관되지 못하게 움직이는 버그가 있다.)
일단 모양새와 제공데이터는 구글 라이트 하우스와 비슷한데, 차이가 있다면 page 별로 데이터도 지원한다는 것이다. 다만 서두에도 말한 것 처럼 vercel을 써야만 누릴 수 있는 기능이라 🤔 근데 라이트 하우스에 비해 크게 차별점도 없다면...
커머스 키트 제공
Next.js가 본격적으로 돈을 벌 만한 비즈니스를 시작하는 것 같다. 간단하게 말헤 next.js로 커머스 사이트를 만들 수 있는 도구를 제공한다고 한다.
리액트 17 지원
react 17을 지원한다. breaking change가 없으므로 바로 적용 가능하며 react를 import 하지 않아도 사용할 수 있는 jsx transform 기능도 사용할 수 있게 되었다.
https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
getStaticProps, getServerSideProps 빠른 새로고침
이제 해당 두 함수에서 코드 변화가 일어나면, 자동으로 새로고침을 지원한다고 한다. 이게 안되었다는 걸 이제 알았는데(??????) 해보니까 잘된다.
써드 파티 리액트 컴포넌트에서 css 임포트 가능
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
이를 바탕으로, 단일 컴포넌트 레벨에서 CSS 코드 스플리팅이 가능해졌다. 자세한 내용은 https://nextjs.org/docs/basic-features/built-in-css-support
href
자동화
이전까지, 다이나믹 라우팅을 사용하기 위해서 next/link
에서 href
as
를 넣어 주어야 했다.
<link href="/categories/[slug]" as="/categories/books" />
여기서 as
는 실제 브라우저 URL 바에서 보이는 주소인데, 이전까지는 href
와 as
를 아래와 같이 따로 넣어주어야 했다.
const pids = ['id1', 'id2', 'id3']
{
pids.map((pid) => (
<Link href="/post/[pid]" as={`/post/${pid}`}>
<a>Post {pid}</a>
</Link>
))
}
그러나 나를 비롯해서 많은 개발자들이 as
의 사용에 대해서 혼란이 있었던 것 같다. (as
를 넣어야 하는데 까먹는 다든지) 그래서 as
가 더 이상 필요없어졌다고 한다. 이제는 기존에 as
에 넣었던 값을 href
에 넣어주면 된다. 그게 훨씬 더 이전의 리액트나 HTML경험에서도 자연스러워 보인다.
@next/codemod
cli
nextjs 에서 기능이 deprecated 되는 등의 대규모 코드 베이스 변경이 필요한 경우에 사용할 수 있는 툴이다. codemode는 소스 코드 업데이트를 위해 프로젝트에서 실행할 수 있는 자동화 코드 변경 툴이다.
https://nextjs.org/docs/advanced-features/codemods
getStaticPaths
에 블로킹 fallback 추가
getStaticProps
와 getStaticPaths
에 fallback
속성이 추가되어 있었다. 이 속성은 최초에는 정적 페이지 (fallback 페이지)를 제공하고, 이후 요청 시에는 완전히 렌더링된 콘텐츠를 제공할 수 있도록 도와주는 기능이었다. 그러나 몇몇 개발자들이, 사용자가 페이지를 처음 요청할때는 사전 렌더링을 차단할 수 있는 옵션을 요구했었나 보다. (나또한 fallback 페이지를 보여주는 것이 사용자들에게 안좋은 사용자 경험을 제공한다고 생각했다. ) 그래서 blocking
옵션이 추가되었다.
export function getStaticPaths() {
return {
fallback: 'blocking',
}
}
이 옵션을 추가하면, fallback 페이지를 보여주는 대신에, 그냥 최초 렌더링이 서버에서 내려올 때 까지 기다린다.
결론
여러가지로 nextjs는 정말로 잘 관리되고 있는 리액트 SSR 프레임워크다. 단순히 nextjs 뿐만 아니라 여러가지로 nextjs를 중심으로 다양한 생태계를 만들어 가려는 것이 보인다.
모질라나 webpack 등 순수하게 기부로 운영되고 있는 대규모 오픈소스 프로젝트들이 코로나 시국이 닥치면서 생존 문제에 직면한 것을 보고 마음이 안타까웠다. 이러한 문제를 vercel도 알고 있는 듯, 여러가지로 수익화를 하려는 노력이 보였다. vercel
, next commerce
등의 비즈니스를 통해서, 단순히 기부에 의존하는 것이 아니라 다각도로 생존에 대해 고민하고 있는 것이 보인다. 개인적으로 다 잘되었으면 하는 바람이다.
회사를 옮기면서 nextjs는 업무에서는 더 이상 쓰지 못하고 있지만 (ㅠㅠ) 블로그나 개인 프로젝트에서는 나름 적극적으로 사용하고 있었다. 심지어 지금 하고있는 nextjs conf 도 꼬박 꼬박 잘챙겨보고 있다. (미리 신청해서 티켓도 받아놨었는데 어디간지 모르겠네)
전 회사 사람들은 next github에 issue 도 올려서 contribute도 했는데 아직도 나는 가져다 쓰고 구글링 하기에 바쁘다 😇
같은, 그리고 연차도 더 많은 개발자로서 부끄럽지 않을 수가 없는 일이다. 조만간 오픈소스에 기여할 날도 오기를 바라며 열심히 공부를 해야겠다.