ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js] Section 06 : 백엔드 개발자가 퇴사했다
    Next.js 2025. 3. 3. 00:59

    reaquest memoization 과 data cache

    Next.js 13부터 **서버 컴포넌트(Server Components)**가 도입되면서 프론트 서버의 부담이 크게 증가했다. 캐싱 전략을 적절히 활용하지 않으면 프론트 서버가 과부하될 수 있기 때문에, 다양한 캐싱 기법을 적용하여 최적화하는 것이 중요하다.

     

    Next.js에서는 프론트 서버의 부담을 줄이기 위해 여러 가지 캐싱 전략을 제공한다.

    (1) Router Cache (라우터 캐시)

    • 클라이언트에서 실행되는 유일한 캐시
    • 브라우저의 메모리에 저장되며, 페이지 이동 시 불필요한 요청을 줄여준다.
    • 페이지를 다시 로드하거나 새로고침하면 캐시가 사라진다.

    (2) Full Route Cache (풀 라우터 캐시)

    • 서버에서 전체 페이지의 HTML과 RSC Payload를 저장하는 캐싱 방식.
    • 정적인 페이지에서 유용하며, 동일한 요청이 왔을 때 캐싱된 데이터를 반환할 수 있다.

    (3) Request Memorization (리퀘스트 메모리제이션)

    • 같은 요청이 반복될 경우, 이전 요청의 결과를 **서버 메모리(In-memory)**에 저장하여 재사용한다.
    • 빠르게 데이터를 불러올 수 있지만, 서버가 재시작되면 캐시가 사라진다.

    (4) Data Cache (데이터 캐시)

    • 데이터 요청 결과(JSON 형태)를 서버에서 **영구 저장(Persistent)**하여 불필요한 API 호출을 줄인다.
    • 데이터베이스 또는 외부 API를 반복해서 호출하지 않고 캐싱된 데이터를 활용할 수 있다.

     

    빌드 (Build Time) 과 리퀘스트 타임 (Request Time)  

     

    빌드 타임

    • 배포 전에 실행되는 빌드 과정
    • 빌드된 결과물을 배포하여 제공
    • 정적인 데이터나 페이지를 미리 최적화하는 것이 중요하다.

    리퀘스트 타임

    • 배포 후,  사용자 요청이 들어왔을 때 발생
    • 실시간으로 데이터를 가져오거나 페이지를 생성할 때 적용
    • 불필요한 요청을 줄이기 위해 캐싱 전략을 잘 활용해야한다. 

    https://nextjs.org/docs/app/building-your-application/caching

     

    Full Route Cache 와 Router Cache

    Full Route Cache를 Opting Out (풀 라우트 캐쉬를 사용하지 않겠다는 경우이다.)

     

    Dynamic API Next 14 버전에서는 기존 이름이 Dynamic Fuction이였는데 이름이 바뀌었다. Dynamic API 쿠키, 헤더, 서치 파라미터 이런걸 사용하고자 할 때는 앞에 await를 붙여줘야 한다. 

     

    dynamic = ‘force-dynamic’ or revalidate = 0 이럴 때는 Full route cache를 사용하지 않는다고 되어 있다

    참고로 Dynamic 페이지인지 아닌지 알아내는 방법이 있다. 

    웹 사이트에 특정 페이지를 띄우면, 왼쪽 하단에 번개 아이콘이 표시가 되는데, 번개가 있으면 Full Route Cache가 적용되지 않은 다이나믹한 페이지다.

     

    데이터 캐시 기본값 변경 (cache: "no-store") 

    이 설정에 대해서 Next에서는 기본값으로 들어 있다고 했었다. 엄밀히 말하면, 
    캐쉬의 기본값이 auto no cache이다. (현재 페이지에서 다이나믹 api가 발견이 되면 매번 요청을 보낸다는거다.) 

     

    no-store Dynamic api가 없더라도 매번 서버의 요청을 보낸다. 정확하게 Dynamic api가 있냐 없냐, fetch 캐싱 동작이 달라진다.

     

    그래서 Full Route Cache는 데이터 캐시와 밀접한 관계가 있다.

     

    . Static Route vs. Dynamic Route의 캐싱 차이

    Next.js 15에서는 Static Route와 Dynamic Route에 따라 Full Route Cache와 Data Cache의 동작이 다르게 적용된다.

    Static Route (스태틱 라우트)

    • Full Route Cache 활성화됨
    • 서버에서 전체 페이지를 캐싱
    • 데이터 캐시는 필요 없음 (한 번 빌드할 때 가져오므로)

    Dynamic Route (다이나믹 라우트)

    • Full Route Cache 사용 불가
    • 다이나믹 API를 사용하여 매번 서버 요청 발생
    • 백엔드와 연결하여 데이터 캐시를 활용

    Router Cache 변경 사항 (Next.js 14 vs. 15)

    Next.js 14에서 Router Cache는 기본적으로 30초~5분 동안 유지되었다.

    • 다이나믹이 아닌 경우 5분 동안 캐싱
    • 다이나믹한 경우 30초 동안 캐싱

    Next.js 14에서 문제점

    • 로그인 후 바로 로그아웃하고 다른 아이디로 로그인하면 이전 프로필이 캐싱되어 남아있는 문제 발생
    • 30초 동안 캐싱이 유지되면서 즉시 변경이 반영되지 않는 버그

    Next.js 15에서 변경점

    • 페이지 단위의 Router Cache가 완전히 삭제됨
    • 이제 Router Cache는 layout.tsx, loading.tsx만 캐싱
    • 페이지들은 기본적으로 Router Cache를 사용하지 않음

     

     

    Statec / ISR / 마이크로프론트엔드


    Next에는 두 가지 배포 모드가 있다. 기존 Page Router에서는 세 가지 모드가 있었지만, 이제 Static , Dynamic 모드만 남았다.

     

    Static 모드 (정적 사이트)

    • 넥스트 서버 없이 HTML 페이지만으로 구성된 정적 사이트
    • 빌드할 때 모든 콘텐츠가 결정됨
    • 서버가 필요하지 않으며, 배포 후에도 변경하려면 다시 빌드해야 함
    • 설정 방법: next.config.js에서 아래 옵션을 추가하면 됨.
       
      module.exports = { output: "export", };
    • EX : 블로그, 뉴스 사이트 등
      • 새로운 게시글이 올라오지만 수정이 많지 않은 경우 Static 모드 사용 가능

    Dynamic 모드 (동적 사이트)

    • 사용자가 요청할 때마다 서버에서 데이터를 가져옴
    • 콘텐츠가 실시간으로 변해야 하는 경우 필요
    • EX : 트위터, 이커머스, 실시간 데이터가 필요한 서비스

    콘텐츠가 자주 변하면 Dynamic 모드 / 자주 변하지 않으면 Static 모드 / Static 모드에서는 서버를 사용할 수 없어 일부 기능이 제한이 있다. 

     

    Incremental Static Regeneration (ISR) – 스태틱과 다이나믹의 중간

     

    ISR 모드란? 

    • Static 모드와 Dynmic 모드의 중간이다. 
    • 새로운 콘텐츠가 추가될 때마다 전체 사이트를 다시 빌드할 필요가 없다. 
    • 점진적으로 새로운 콘텐츠를 생성하여 업데이트가 가능하다.

    ISR 사용하는 이유

    • 블로그에서 새로운 글을 올릴 때마다 전체 사이트를 다시 빌드하는 건 부담스러움
    • 하지만 전체 사이트를 Dynamic 모드로 바꾸면 서버 부담이 커짐
    • ISR 모드를 사용하면 처음 일부 콘텐츠만 미리 빌드하고, 이후 콘텐츠는 필요할 때 생성

     

    배포 직전 빌드하기

    Next에서 배포 직전에는 빌드를 해야 한다. 

     

    npm run build -> Finalizing page 메시지가 나오면 빌드가 성공을 한거다.

     

    빌드 완료 후 각 페이지별 자바스크립트 다운로드 크기를 확인을 할 수 있다. 

     

    권장 크기는 300KB 이하이다. 이 속도를 유지해야 빠르게 로딩이 된다. 

    Next의 장점은 스플리팅이다.

     

    페이지 별로 코드가 쪼개져 있어서 기본적으로 용량이 낮다.

    용량이 큰 경우는, 대부분 라이브러리 때문이다. 특정 라이브러리를 import 하면 해당 라이브러리의 크기가 포함이 된다. 

     

     

    웹소켓을 활용한 실시간 채팅 구현하기

     

    웹소켓은 단순히 메시지를 주고받는 것뿐만 아니라, 다양한 실시간 기능을 구현할 수 있다.

     

    웹소켓 활용 

    • 실시간 채팅
    • 실시간 알림
    • 새로운 게시글 자동 등록 알림
    • 서버에서 클라이언트로 데이터 push (HTTP 요청 없이 서버가 먼저 전송) 

    서버 컴포넌트에서 Socket.IO 사용 주의 (메모리 누수 발생 가능)

     

    메모리 누수란 :

    • 아무 작업도 안 했는데 메모리가 계속 증가하는 현상
    • 컴퓨터는 메모리 한계가 있어서, 이를 초과하면 서버가 다운될 수 있다.

     

    서버 컴포넌트에서 Socket.IO 사용하면 메모리 누수가 발생할 수 있다. 

     

    WebSocket과 HTTP 폴링(Polling) 차이점

    WebSocket (웹소켓)

    • 서버와 클라이언트가 한 번 연결되면, 계속 데이터를 주고받을 수 있음
    • 서버가 먼저 데이터를 보내는 것도 가능 → 실시간 기능 구현에 적합

    HTTP Polling (HTTP 폴링)

    • 클라이언트가 주기적으로 서버에 요청을 보내 새로운 데이터가 있는지 확인
    • 웹소켓이 없던 시절에는 서버에서 클라이언트로 데이터를 보낼 방법이 없어서 폴링을 사용

    Socket.IO는 WebSocket을 지원하지만, 구형 브라우저에서도 동작할 수 있도록 HTTP 폴링도 지원

    • 옵션 설정 → 웹소켓을 우선 사용하고, 지원되지 않으면 HTTP 폴링을 사용하도록 설정 가능
      transports: ["websocket"]
Designed by Tistory.