이 글은 smashing magazine의
“A Look At Remix And The Differences With Next.js“
라는 기사를 참고했습니다.
개발자 커뮤니티에는 매일 새로운 프레임워크와 도구가 등장하는데, 그 중 일부는 현재 다른 도구로 해결 중인 시나리오를 해결할 수 있는 다른 접근 방식을 제공하기도 하고, 또 다른 일부는 새로운 개념이나 아이디어를 가져와 프로젝트를 대하는 다른 방법을 제안하기도 합니다.
개발자들 역시 다양한 사용 사례에 적합한 여러 프레임워크와 라이브러리를 시도하는 경우가 많은데, Remix는 서버사이드 렌더링을 사용하는 자바스크립트 프로젝트를 만드는 새로운 프레임워크로, 기존의 유사한 기능을 제공하는 자바스크립트 프레임워크인 Next.js와는 다른 방법을 제안하고 있습니다.
Remix는 오픈소스가 된지 얼마 되지 않았지만, 웹 표준을 따라 프로젝트를 만들고 협업하는 매우 활발한 커뮤니티를 가지고 있는 만큼, 앞으로가 기대되는 프레임워크라고 합니다.
Remix란?
Remix 공식 웹사이트에 따르면, Remix는 개발자들이 웹 표준에 초점을 맞춘 훌륭한 사용자 경험을 만들 수 있도록 해주는 엣지 우선 풀 스택 프레임워크입니다.
즉, Remix를 통해 React와 자바스크립트를 사용한 클라이언트 사이드 렌더링, 서버 사이드 렌더링 웹 애플리케이션을 모두 만들 수 있는데, 웹 Fetch API를 기반으로 하기 때문에 Remix로 만든 애플리케이션은 어디에서나 실행 할 수 있고, 서버사이드 렌더링을 사용하여 데이터를 조작하고 서버에서 HTML 콘텐츠를 렌더링하기 때문에 클라이언트에는 가능한 적은 양의 자바스크립트를 보낼 수 있습니다.
Remix는 원래 구독 기반의 프리미엄 프레임워크였지만, 1년도 채 되지 않아 오픈 소스 프레임워크로 출시되었고, 이렇게 오픈 소스 프레임워크로 출시되면서 Remix 개발자들과 사용자의 커뮤니티가 성장하고 인기를 얻기 시작했습니다.
Remix의 주요 기능
Remix에서 제공하는 몇 가지 주요 기능은 다음과 같습니다.
- 라우트
- Remix는 다른 프레임워크와 마찬가지로 웹 프로젝트의 다양한 라우트를 핸들러 함수를 포함하고 있는 자바스크립트 또는 타입스크립트 파일을 통해 관리할 수 있도록 제공하고 있습니다.
- Remix는 프로젝트의 파일 시스템 계층을 따르는 파일을 만들어 페이지에 대한 아날로그 URL을 만들고 라우트를 생성할 수 있는데, Remix 라우터는 React-Router가 제공하는 라우팅 기능 중 일부를 사용하여 작동하기 때문에, 이러한 접근 방식을 염두에 두면 다음과 같이 몇 가지 이점을 확인할 수 있습니다.
- 중첩된 컴포넌트
- Remix를 사용하면 중첩된 페이지와 컴포넌트를 관리할 수 있는데, 특정 라우트를 처리할 파일을 만들고 파일 시스템의 동일한 수준에서 동일한 이름을 가진 폴더를 만들 수 있습니다. 해당 폴더 내에 만드는 모든 파일은 서로 다른 페이지가 아닌 상위 경로의 중첩된 컴포넌트가 됩니다.
- 에러 핸들링
- 중첩된 컴포넌트는 특정 컴포넌트를 렌더링하는 동안 에러가 발생하더라도 페이지의 다른 중첩된 부분에는 영향을 주지 않습니다. 즉 일반적인 페이지 에러가 발생하는 대신 에러가 발생한 부분에 에러를 캡슐화할 수 있습니다.
- 폼
- Remix는 웹 표준에 중점을 두고 있기 때문에 자바스크립트를 사용하는 대신 기본 메서드인
POST
,PUT
,DELETE
,PATCH
를 사용하여 폼을 처리합니다. - Loaders와 Actions
- Remix는 서버사이드 동적 콘텐츠를 만들기 위해 두 가지 함수를 제공하는데,
loader
함수는 서버에서GET
HTTP 요청을 처리하거나, 주로 다른 소스로부터 데이터를 가져오는 데 사용되고,action
함수는 데이터 조작과 수정에 중점을 두고POST
,PUT
,DELETE
,PATCH
요청을 모니터링합니다.
여기까지가 Remix의 주요 기능인데, 현재 가장 많이 사용되고 있는 React 프레임워크 중 하나인 Next.js와 비교해 보면 그 차이를 조금 더 잘 알 수 있습니다.
Remix와 Next.Js
Next.js와 Remix는 같은 목표를 갖고 있는 것처럼 보이지만, 두 프레임워크가 제공하는 특징과 접근방식을 분석해보면 유사한 점과 차이점을 파악할 수 있습니다. 이렇게 두 프레임워크의 차이를 파악하면 각 시나리오별로 어떤 프레임워크가 더 적합한지 판단할 수 있는 기준이 생길 수 있습니다.
REACT 기반 프레임워크
두 프레임워크는 모두 React를 기반으로 만들어졌지만 Remix는 더 높은 수준의 추상화를 제공하고 있어. 또 Remix 커뮤니티의 구성원들은 Vue.js와 Angular 및 Svelte 같은 다른 프레임워크를 사용한 구현도 진행하고 있는 반면, Next.js는 React에 의존하고 있고, 현재 이를 변경할 계획은 없는 것 같습니다.
서버사이드 렌더링
Remix와 Next.js는 모두 서버 사이드 렌더링을 제공하여 웹 서버에서 페이지의 마크업과 콘텐츠를 생성한 후 클라이언트로 전송하는데, Next.js와 Remix는 모두 React를 사용하기 때문에 클라이언트 사이드 하이드레이션과 같은 기능에 의존 할 수 밖에 없습니다.
또 두 프레임워크 모두 서버에서 HTML을 미리 렌더링하는 것도 지원하는데, 프로젝트에 따라 서버 측에서 가능한 한 많은 콘텐츠를 생성하여 자바스크립트 코드 전송을 피하고 클라이언트에서 데이터를 가져오지 않도록 하는 기능을 제공합니다.
정적 사이트 생성
Next.js는 정적 사이트 생성을 사용하여 빌드 시 정적 페이지와 콘텐츠를 사전에 생성할 수 있는 반면, Remix는 그렇지 않습니다.
SSG는 만들려는 페이지 유형에 따라 큰 이점을 제공할 수 있는데, SSG를 사용하면 빌드 타임에 데이터를 가져오고 페이지를 렌더링 할 수 있는 장점이 있습니다. 즉 SSG는 사용자가 웹 사이트를 방문하기 전에 정적 페이지를 생성하기 때문에 사용자는 콘텐츠가 생성될 때까지 기다릴 필요가 없는 것이죠.
하지만 반대로 SSG는 문제가 될 수도 있는데, 코드나 애플리케이션의 내용을 변경할 때마다 새 버전의 정적 assets을 생성하기 위해 빌드 프로세스를 기다려야 하기 때문입니다. 즉 프로젝트가 커짐에 따라 빌드 시간이 늘어나기 때문에 문제가 될 수 있는 건데, 이 문제를 해결하기 위해 Next.js 팀은 ISR이라는 기능과 새로운 온디맨드 ISR을 개발했다고 합니다.
STALE WHILE REVALIDATE
Remix는 콘텐츠를 최대한 빨리 제공하기 위해 stale-while-revalidate 캐싱 디렉티브를 사용하는데, SWR은 정적 콘텐츠를 미리 생성하는 대신 앱이 트래픽을 받으면 캐시를 준비하는 것으로, 페이지와 문서는 캐시에서 제공되고 다음 방문자를 위해 백그라운드에서 유효성을 다시 검증하게 됩니다.
Next.js도 stale-while-revalidate로 작업을 할 수 있는데, getServerSideProps
함수 내에서 stale-while-revalidate 캐시 제어 헤더를 사용할 수 있습니다.
클라이언트 사이드 내비게이션
사용자에게 원활한 내비게이션을 제공하기 위해 Next.js가 사용하는 기능 중 하나는 프리패치라는 기능으로, 우리는 웹 사이트에서 엘리먼트가 뷰포트에 나타날 때 <link>
가 리다이렉션하는 페이지를 미리 로드하기 위해 <Link>
컴포넌트를 사용할 수 있습니다.
예를 들어 홈페이지를 방문했을 때 페이지에 “연락처”라는 링크가 나타나면 Next.js가 연락처 페이지와 관련된 내용을 다운로드하여 가져오기 때문에, 링크를 클릭할 때 페이지가 다운로드될 때까지 기다릴 필요가 없는 것이죠.
그렇지만 Link
컴포넌트는 정적 사이트 생성을 사용하여 사전에 작성된 페이지에 대해서만 프리패치를 제공한다는 한계가 있습니다. 즉 동적으로 생성되는 페이지에는 링크가 있어도 이 기능이 적용되지 않습니다.
Remix는 Next.js의 Link 컴포넌트처럼 캐시를 사용하는 대신 HTML의 <link rel="prefetch">
태그를 사용하기 때문에 링크 뿐만 아니라 어떤 페이지든 프리패치를 할 수 있습니다. 만약 Next.js를 사용하여 이와 비슷하게 구현해야 한다면 next/head
컴포넌트에 prefetch
태그를 추가하여 구현할 수 있습니다.
엣지 우선
서버에서 데이터를 가져오고 콘텐츠를 렌더링한다면, HTTP 요청을 보내는 사용자로부터 코드를 실행하는 서버가 얼마나 멀리 떨어져 있는지도 평가해야 할 요소 중에 하나입니다.
만약 메인 서버가 브라질에 있고 중국에서 웹사이트를 방문한다면, 페이지를 로딩하는 과정은 아르헨티나에서 같은 페이지를 방문하는 것보다 더 느릴 수 밖에 없는데, 이것은 HTTP 요청이 코드를 평가하고 실행하기 위해 가까운 서버까지 도달해야 하는 물리적 거리와 관련이 있습니다.
최신 애플리케이션들은 정적 콘텐츠의 전달은 CDN에 의존하지만, 동적 콘텐츠를 생성하기 위해 처리되는 서버측 코드는 일반적으로 데이터 센터에서 실행되거나, 특정 위치에서 실행이 되는데, 이 문제에 대한 일시적인 해결책은 CDN이 리소스를 새로 고치는 동안 오래된 콘텐츠를 제공 할 수 있는 위험을 감수하면서 SWR 캐싱 디렉티브를 사용하는 겁니다.
이런 문제를 해결하기 위해 지난 몇 년 동안 새로운 개념이 고안되었는데 이것이 바로 엣지 컴퓨팅입니다. 이 아이디어는 CDN을 사용하는 것과 동일한 접근 방식으로, 다른 서버와 다른 위치에 있는 서버 로직을 복제하고, 가능한 사용자 가까이에서 동적 코드를 실행하는 겁니다.
Remix는 “엣지 우선“으로 정의된 프레임워크인 만큼 개념에서 부터 Edge에서 실행되는 것으로 생각되는데, Next.js 에서 제공하는 배포플랫폼인 Vercel은 플랫폼에 배포된 애플리케이션을 위한 추가 기능으로 Edge Functions를 출시했습니다.
서버 사이드 코드
Remix는 기본 HTTP 메서드를 사용하여 action
과 loader
함수의 도움을 받아 폼을 관리하는데, 폼, 서버, 폼의 직렬화된 데이터를 서버로 전송하는 POST
요청과 서버 측 작업, 요청의 결과로 새 페이지까지, 웹 표준을 유지할 수 있습니다.
Remix는 HTML 폼의 최적화된 버전인 <Form>
엘리먼트를 제공하는데, <Form>
엘리먼트와 action
함수를 통해, 해당 경로와 관련된 클라이언트 코드와 서버 코드를 모두 같은 파일에 작성할 수 있고, 이런 특징으로 Remix는 페이지의 사용자 인터페이스와 요청과 관련된 서버 측 동작을 관리하는 방법 모두를 알수 있어서 컨텍스트와 상태 관리를 사용할 필요가 없습니다.
반면 Next.js는 애플리케이션의 상태를 어떻게 관리하고, 어떤 API를 호출하고, 어떻게 데이터를 재검증하고, 어떻게 웹 페이지의 인터페이스를 업데이트하는지와 같은 방법을 자바스크립트 코드에 의존하지만, API Routes를 사용하면 서버 측 기능을 실행하고 프런트엔드로 데이터를 반환하도록 파일을 분리할 수 있습니다.
NODE.JS
Remix는 Node.js에 의존하는 대신 웹 Fetch API를 기반으로 하기 때문에, Vercel, Netlify와 같은 Node.js 서버뿐만 아니라 Cloudflare Workers, Deno Deploy와 같은 다른 유형의 플랫폼에서도 Remix 애플리케이션을 실행할 수 있습니다.
Next.js의 경우 최신 버전인 12.2버전을 사용하면 기본 Node.js 런타임 대신 전체 Next.js 프로젝트에 대한 엣지 런타임을 선택할 수 있습니다.
smashing magazine, “A Look At Remix And The Differences With Next.js“