실무에서 Next.js 프로젝트 개발 경험을 토대로 풀어낸 글입니다.

javaScript 기반이야..? ok. React랑 비슷하다고? ok.
고작 몇분 검색하고 Next.js에 대해 느낀 첫 인상으로 기억합니다. Angular와 React에 대한 경험이 있어서 nodejs 기반 웹 개발이 낯선 편은 아니었습니다. 팀에선 Next.js 사용 목적이 명확했고 그 개발 과정에서 Next.js의 새로운 장점을 체감했습니다. Next.js는 React의 한계와 성능을 개선시켜 Vercel 팀에서 개발한 프레임워크 입니다. (조직원 50명 정도라며… 놀랍다 진짜) 몇 달 정도 개발하면서 느낀 Next.js의 매력을 한번 써보려고 합니다.

next.js는 어떤 성능을 고민하여 설계된 프레임워크인가?

일단 구현 방식은 React와 거의 동일했습니다. 페이지를 구성하는 컴포넌트 단위 개발 방식인데 컴포넌트, Hook 메서드를 사용할때 React 라이브러리를 사용하더군요. 조금 다른 점이 있다면 클라이언트 부하를 줄이기 위해 내부적으로 React와 동작이 약간 다릅니다. 또한 그 동작을 수행하는 메서드(getServerSideProps, getStaticProps 등)를 지원합니다. 이는 유저 경험개발자 경험을 개선시키기 위한 vercel팀의 흔적으로 보입니다.

  • getStaticProps : 컴포넌트에 필요한 데이터를 fetch할때 쓰는 메서드로 컴포넌트에 넘겨줄 props를 반환 (Static-Generation)
  • getServerSideProps : 컴포넌트에 필요한 동적 데이터를 fetch할때 쓰는 메서드로 컴포넌트에 넘겨줄 props를 반환 (Server-side Rendering)

SSR(Server-side Rendering)

컴포넌트 렌더링은 html을 생성하는 물리적 위치에 따라 크게 두 가지 타입으로 나뉩니다. Client-side Rendering(CSR)은 브라우저에서 마크업(html) 파일을 만듭니다. SSR은 서버에서 미리 만든 마크업(html) 파일을 클라이언트에게 전송합니다. Next.js는 유저의 요청이 서버에 도착할때 마다 렌더링을 하는것이 아니라 이전에 만들어진 파일을 재사용 하기 때문에 유저는 빠른 응답을 받을 수 있지요.

Next.js 프로젝트를 처음 생성하면 root에 pages 폴더가 자동으로 생성됩니다. 폴더 하위에 생성된 컴포넌트는 next가 빌드타임에 static page로 미리 만들어 줍니다. 그래서 URL 경로로 해당 페이지에 즉각 접근할 수 있습니다. SSR방식에서 얻을 수 있는 UX 측면의 여러 장점 중 제가 체감한 바는 아래쪽에서 설명 할 ‘웹 속도’‘검색 엔진’ 의 성능인것 같습니다.

NextJS가 지원하는 렌더링 방식

  • 빌드 타임에 미리 마크업(html)을 생성 (static generation)
  • 런타임에 서버 측에서 마크업(html)을 생성 (server-side rendering)
  • 런타임에 브라우저 측에서 html을 생성 (client-side rendering)

웹 속도 최적화의 측면

next.js로 구현한 웹 사이트는 속도 면에서 성능이 뛰어날 수 밖에 없습니다. pages 하위 폴더에 생성한 컴포넌트를 next가 빌드타임에 미리 만들어 놓은 static page를 클라이언트에게 전송하기 때문입니다. 브라우저는 전송받은 page를 paint 합니다. 프로젝트의 규모에 따라서 웹애플리케이션의 초기 로드 속도는 조금씩 차이가 있을 수 있지만 그 이후 발생하는 page 렌더링 속도는 상대적으로 절감 됩니다. (클라이언트에 전송되면 js를 따로 fetch하지 않으니 용량에 대한 장점도 있지 않을까?)

최근 버전 10 출시에서 발표한 기본 기능 업데이트 중 하나는 이미지가 많은 페이지의 초기 뷰포트 성능을 개선하는 이미지 컴포넌트 입니다. 크롬의 경우 로드 하려는 페이지에서 첫 뷰포트 밖에 있는 이미지 중 30%를 로드하는 정책을 갖고 있습니다. 그 이미지는 유저가 스크롤을 내리지 않으면 볼 일이 없는 데이터 이므로 이에 대한 부하를 줄이기 위해 이미지 컴포넌트 기능을 만들었습니다. 이미지 컴포넌트를 사용하면 첫 뷰포트의 밖에 있는 이미지는 로드하지 않아 페이지 첫 로딩 속도를 감소시키는 효과가 있다고 합니다. 이미지 컴포넌트에 대해 더 알고싶다면 공식문서를 확인해봅시다. 공식문서

검색엔진 최적화(Search Engine Optimization)의 측면

특정 단어를 입력했을 때 딱 필요한 사이트가 나온다면 그건 사이트가 검색엔진에 최적화가 잘 되었다는 의미입니다. 사이트 검색엔진 최적화가 잘 되려면 사이트 자체에서 몇 가지 설정을 필요가 있습니다. 그런데 next.js의 SSR 동작 방식검색 엔진이랑 무슨 관련이 있냐구요? 저도 몰랐습니다… 꽤 있더군요…

온갖 도메인 사이트를 돌아다니며 어떤 페이지에 어떤 단어나 글자가 있는지 파악하는 Robot이란 놈이 있습니다. 이 Robot은 구글, 페이스북 등 검색엔진을 이용하는 플랫폼 마다 존재하여 유저가 검색한 글자를 기반으로 사이트를 샅샅이 뒤지고 찾은 결과를 보여 줍니다. 그런데 사이트를 뒤지는 과정에서 Robot은 URL로 접근 가능한 페이지를 대상으로 글자를 검토합니다. 이 말은 url로 접근한 페이지가 동적으로 바뀌는 조각을 갖고 있다고 가정할때 이 조각의 존재에 대해서는 알지 못한다는 의미입니다. 이 조각이 어떤 글자를 포함하는지, 어떤 이미지를 포함하는지 말입니다. (여기서 조각은 컴포넌트를 의미합니다) 위에서 Next.js는 서버에서 컴포넌트를 미리 만들어 놓는다는 이야기를 했습니다. 풀어 설명하자면 어떤 동작이 취해져야만 렌더링 되는 컴포넌트는 Robot이 알 수 없습니다. 그러나 이미 만들어진 컴포넌트는 Robot이 발견할 수 있고 그 컴포넌트에 포함된 글자를 알 수 있겠지요.

웹 기술이 점점 발전할수록 SEO 방식 또한 다양할 것입니다. 저도 주니어 개발자로 SEO를 배워가는 입장입니다만 페이지에 포함된 글자를 찾는건 검색엔진 최적화의 아주 기본적인 방식..이라고 추측하고 있습니다. 검색엔진을 보유한 플랫폼마다 공통적으로 이용하는 보편성이 있으니까요. 이 기본적이고 보편적인 방식을 효율적으로 이용할 수 있는건 SSR 렌더링 동작 애플리케이션이 가진 큰 장점 이라고 생각합니다.

어떤 사이트 모델에서 더욱 유리하게 작용할까?

컴포넌트에 fetch할 데이터가 많을수록 유저가 페이지 로딩을 대기하는 시간이 비례로 늘어납니다. 서비스에 대해 고객의 충성도가 높은 사이트라면 ‘페이지 로딩 시간으로 인한 이탈률’은 주요 우선순위가 아닐 것 같습니다. 그러나 신생 웹 서비스 혹은 주요 마케팅 타겟 페이지라면 이탈률에 대한 관리가 우선순위가 좀 더 높으며 ‘이탈률에 영향을 미치는 요인’을 고려하지 않을까 싶습니다.

vercel이 최근 릴리즈에서 언급한 내용 중 인상이 깊었던 부분이 있었습니다. 버전에서 기능 추가를 고려할때 Next.js 프로젝트를 개발하는 개발자들을 대상으로 진행한 기술 survey 결과를 참조했다고 합니다. 개발자들과 직접 커뮤니케이션 함으로서 추가된 기능은 전 필요성을 느끼진 못했지만 ‘많은 개발자들이 이런 이슈를 공통으로 갖고 있군’ 하는 생각이 들었어요.

한편으론 “이런 마이너리티 기능이 새로 추가될 정도면 웬만한 기능들은 다 있다는 말인가..?” 싶기도 했고요. 참고로 전 이번 릴리즈에서 지원한 “국제화 된 라우팅” 기능이 가장 궁금하네요. 몇 가지 모듈 추가로 자동으로 페이지를 번역할 수 있는 기능인데 사이트가 해외 진출을 공략하는 비즈니스 모델이라면 외부 라이브러리 사용 없이 도전해볼 가치가 있을 것 같네요. (번역 성능 기대중) Vercel이 그리는 next.js의 미래는 비즈니스 측면에서 유용한 가치가 있지 않을까.. 하는 추측을 해봅니다.


제가 Next.js를 고작 몇달 써보고 쓴 글이라 매우 주관적일 수 있습니다. 단점도 여러번 맛본것 같은데 추후에 생각날때 마다 내용을 추가할 생각입니다. 사실과 다른 내용이거나 수정이 필요하다고 생각되는 부분이 있다면 코멘트를 달아주세요. Next.js에 대한 다른 평가가 있다면 언제든지 환영입니다!