정말 고민이 많았던 주제였습니다. 함께하는 동료 프론트엔드 개발자도 axios를 주로 사용했던 터라 axios의 편의성을 고려해 axios를 사용하는 것이 좋은지 Next.js에서 최적화하고 권장하는 fetch를 사용하는 것이 좋은지 고민이 많았습니다. 편리한 axios를 그대로 사용하고 싶었지만 Next.js에서는 강력히 fetch를 권장하고 있기에 과연 axios의 편리함을 저버릴만큼 fetch 사용에 이점이 있는가..?에 대해 알아보고자 어려 자료들을 찾아봤고, 결국에는 fetch를 사용하기로 결정했습니다. 그 과정을 정리해보겠습니다 :)
Axios와 Fetch에 대해 먼저 알아보자!
먼저 Axios와 Fetch에 대해 각각 알아보는게 좋을거 같습니다!
Axios
공식 문서 내용 :
Axios는 node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트 입니다. 그것은 동형 입니다(동일한 코드베이스로 브라우저와 node.js에서 실행할 수 있습니다). 서버 사이드에서는 네이티브 node.js의 http 모듈을 사용하고, 클라이언트(브라우저)에서는 XMLHttpRequests를 사용합니다.
- XMLHttpRequest (브라우저)와 http 모듈 (Node.js)을 내부적으로 사용
- 자동 JSON 파싱, 인터셉터, 요청 취소, 타임아웃 등 고급 기능을 제공
- HTTP 에러도 자동 reject
- 구형 브라우저까지 지원
- 라이브러리이기에 별도 설치 필요 → 번들 크기 증가
Fetch
공식문서 내용 :
Fetch API는 네트워크 통신을 포함한 리소스 취득을 위한 인터페이스를 제공하며, XMLHttpRequest보다 강력하고 유연한 대체제입니다.
- 네이티브 Web API로, 브라우저와 Node.js 18+에서 기본 제공
- Promise 기반이며, 간결한 문법과 최신 웹 표준을 준수
- Next.js 15에서는 서버 컴포넌트와의 심층 통합으로 최적화된 성능을 제공
- 네트워크 에러만 reject, HTTP 에러는 수동으로 처리 필요
- 추가 번들 크기 증가 x
XMLHttpRequest란 무엇인가?
Ajax에서 사용되는 HTTP 통신을 위한 메서드와 프로퍼티를 제공하는 객체입니다. 여기서 Ajax는 Asynchronous JavaScript와 XML의 약어로 XMLHttpRequest 기술을 사용해 복잡하고 동적인 웹페이지를 구성하는 프로그래밍 방식입니다. 조금 어렵게 설명되어 있는데, 간단하게 설명하자면,
웹 페이지를 새로고침하지 않고도, 자바스크립트를 이용하여 서버와 비동기적으로 데이터를 받을 수 있게 해준 기술입니다. 그 전에는 웹 페이지에서 변경사항이 있을 때 html 전체 파일을 서버로부터 전송받아 처음부터 다시 렌더링 해 주는 방식을 사용했고, 이는 불필요한 통신과 화면 깜빡임 현상 그리고 동기 방식이기에 서버 응답이 있을때까지 다음 처리를 하지 못하는 단점을 가지고 있었습니다. Ajax를 이용해 이러한 문제를 개선한 것이죠!
XMLHttpRequest는 Promise를 반환하지 않기 때문에 콜백 함수를 직접 작성하거나 Promise로 감싸서 체이닝 문법을 사용할 수 있습니다. axios는 내부적으로 XMLHttpRequest를 Promise로 감싸서 Promise를 반환할 수 있게 하여 then과 catch와 같은 체이닝 문법이나 async/await 문법을 사용할 수 있도록 하는 것입니다.
아직은 fetch가 왜 더 좋은지 잘 모르겠다..!! Next.js에서 axios는 어떤 문제가 있고, fetch는 어떤 이점이 있는가
이렇게 각 기능들을 살펴 보았을때, 아직까지는 fetch의 이점이 두드러지지는 않는다고 생각합니다.
그래서 더 알아본 결과 Next.js에서 axios를 사용하는 경우 다음과 같은 문제를 야기할 수 있다고 하더라고요
- 캐싱/ISR 등 Next.js의 서버 기능과 완벽하게 연동되지 않음:
- axios로 데이터를 패칭하면 Next.js의 내장 fetch 기반 캐싱이나 revalidate, 중복 제거 기능을 직접 구현해야 하거나, 일부 기능이 제한될 수 있습니다.
- ISR( Incremental Static Regeneration, 증분 정적 재생성 )이란 무엇이죠? :
페이지 빌드 시점에 미리 정적 HTML로 만들어 두어 사용자에게 빠른 속도로 페이지를 제공할 수 있게 하는 개념입니다. 한 번 생성하나 정적 페이지에 대해 시간을 설정하여 다음 요청이 들어올 때 백그라운드에서 최신 데이터로 다시 생성하고, 전체 사이트를 다시 빌드하지 않고, 변경된 페이지만 선택적으로 갱신할 수 있게 합니다.
요약해서 이야기하면 정적 사이트 생성(SSG)과 서버사이드 렌더링(SSR)의 장점을 결합한 하이브리드 방식입니다!
- ISR( Incremental Static Regeneration, 증분 정적 재생성 )이란 무엇이죠? :
- 서버 컴포넌트에서 window 객체 참조 등 이슈:
- axios는 내부적으로 XMLHttpRequest를 사용하기 때문에, 서버 환경에서 일부 브라우저 전용 API를 사용할 경우 문제가 발생할 수 있습니다.
그리고 Next.js에서 fetch를 권장하는 이유도 함께 찾아보았습니다.
1. 서버 컴포넌트와의 완벽한 통합
- Next.js의 fetch는 브라우저의 기본 fetch를 확장한 API로, 서버 컴포넌트(Server Components), Route Handlers, Server Actions 등에서 네이티브하게 사용할 수 있습니다.
- 서버 컴포넌트에서 fetch를 사용하면, Next.js가 데이터 패칭, SSR(서버사이드 렌더링), SSG(정적 사이트 생성), ISR(증분 정적 재생성) 등 다양한 데이터 패칭 전략과 연동해 최적의 성능과 개발 경험을 제공합니다.
2. 명시적 캐싱 및 데이터 갱신 제어
- 명시적으로 캐싱 방식을 지정하여 원하는 방식으로 데이터 페칭을 할 수 있습니다.
- Next.js 15에서는 fetch가 기본적으로 캐싱을 하지 않으므로, 개발자가 명확하게 캐싱 정책을 지정해야 합니다.
- 예를 들어, **{ cache: 'force-cache' }**로 영속 캐시, **{ cache: 'no-store' }**로 비캐시, **{ next: { revalidate: 10 } }**로 ISR을 구현할 수 있습니다. (ISR이란)
- 캐싱과 재검증 옵션을 fetch의 옵션 객체로 직접 제어할 수 있어, 데이터 신선도와 성능을 세밀하게 조절할 수 있습니다.
3. 자동 중복 제거 및 최적화
- 여러 컴포넌트에서 동일한 fetch 요청이 발생해도, Next.js는 자동으로 요청을 중복 제거(deduplication)하고 임시 캐시에 저장해 한 번만 네트워크 요청을 보냅니다6.
- 이는 렌더링 성능을 높이고, 불필요한 네트워크 트래픽을 줄여줍니다.
4. Streaming, Suspense 등 최신 React 기능과의 연동
- fetch는 Next.js의 Streaming, React Suspense 등 최신 기능과 호환되어, 점진적 렌더링과 빠른 사용자 경험을 제공합니다.
- 데이터 패칭이 완료된 부분부터 점진적으로 UI를 렌더링할 수 있습니다.
5. 번들 크기 최소화 및 표준화
- fetch는 브라우저와 Node.js에 내장된 표준 Web API이므로, 추가 라이브러리 설치가 필요 없고 번들 크기가 증가하지 않습니다.
- axios 등 서드파티 라이브러리는 번들 크기를 늘리고, Next.js의 서버 기능과 완벽하게 연동되지 않을 수 있습니다.
결국 이러한 내용들을 기반으로 고민하여 fetch를 사용하기로 결정했습니다! 그리고 더 찾아보니까 axios의 편의성을 취할 수 있도록 하는 fetch 기반의 라이브러리가 있더라고요. 하지만 번들 크기를 키울 수 있고, 러닝커브 및 Next.sj와의 호환성 문제가 있을것이라 판단하여 fetch 그 자체를 사용하기로 했습니다.