SSR VS CSR ...? (트러블 슈팅🚨)

최창연·2025년 3월 19일
0

트러블 슈팅

목록 보기
5/6
post-thumbnail

이번 프로젝트는 Next를 통해서 구현하는 내용이였다.
Next의 대표적인 라우팅 기법에는 App RouterPage Router가 있는데 그 중 App Router를 사용하고자 했다.

그 이유로 서버 컴포넌트클라이언트 컴포넌트를 나눠서 사용하기 위함이였다.

그럼 서버 컴포넌트와 클라이언트 컴포넌트가 뭔데?

둘 다 컴포넌트다. 기본적으로는
근데 실행되는 위치가 다르다. 서버 컴포넌트는 서버 측에서 실행되고 클라이언트 컴포넌트는 브라우저에서 실행된다.

왜 이렇게 나눴을까?
서버 컴포넌트는 서버측에서 미리 코드를 실행해서 HTML 빌드까지 완료시켜서 브라우저의 렌더링 로딩 속도를 줄일 수 있게되어 UX 측면에서 아주 중요한 부분이다. 그러나 미리 빌드를 하여 클라이언트 번들에 속하지 않기 때문에 사용자의 동적인 내용을 처리할 수 없다.

그런 부분을 처리하기 위해서 클라이언트 컴포넌트가 존재한다.
이 컴포넌트는 미리 빌드되는 것이 아니라 브라우저에서 빌드되어 렌더링되기에 로딩에 시간이 걸린다. 그렇지만 사용자의 동적인 내용을 처리할 수 있고, 그에 따른 리랜더링도 가능하다.

근데 이걸 왜 얘기했느냐...?

내가 이번 프로젝트에서 클라이언트 컴포넌트로 구현한 페이지는 로테이션 페이지로 라이엇으로부터 정보를 받아와서 해당 정보를 통해 챔피언 카드 컴포넌트를 구성하는 컨텐츠였다.

그런데 여기서 비동기 처리가 진행되는 코드 부분이 총 2가지가 있었다.

1. 서버로부터 데이터를 받아오는 부분
2. 이미지 URL 검증을 위해 서버로부터 버전 정보를 받아오는 부분

근데 비동기 처리를 왜 지금 확인하는가..?

사실 위에서 얘기를 다하지 못했지만 클라이언트 컴포넌트는 async/await를 사용할 수 없다.
이유인 즉슨, 클라이언트 컴포넌트를 렌더링이후 즉시 JSX를 반환되도록 설계했기 때문이다. 이에 대한 자세한 설명...

간단히 얘기를 하자면

  1. 서버 컴포넌트(미리 빌드) -> 브라우저 렌더링(이때 Dom Tree 생성)
  2. 클라이언트 컴포넌트(이후 빌드) -(로딩...)-> 서버 컴포넌트 Tree가 재조정
  3. Hydration (이벤트 리스너들이 Dom Tree에 붙여지는 과정)
  4. 이후 비동기 작업들은 React hook을 통해서 실행

즉, 클라이언트 컴포넌트에서 직접적인 비동기 작업은 위 과정에서 불필요한 기다림(랜더링이 이뤄지지 않기에)인 것이고 UX 측면에서 매우 불량한 Products인 것이다.

그럼 위에서 비동기 작업은 hook을 통해서 하면되는 것 아닌가?

맞다..
사실 챔피언 카드 컴포넌트를 로테이션 페이지 말고도 미리 구현해 놓았었다.
해당 페이지에선 SSR 방식을 통해서 미리 데이터를 빌드하는 형태였다.
그러나 컴포넌트 구현 코드가 동일하기에 (CSS나 UI적인 측면에서) 이미 사용했던 코드를 재사용해야겠다는 생각이 들었다.

하지만 간과한 내용이 바로 위에서 설명한 내용..
비동기로 처리되는 부분 중 2번 내용!
2. 이미지 URL 검증을 위해 서버로부터 버전 정보를 받아오는 부분
해당 내용을 위해 SSR 방식의 페이지에서 비동기 컴포넌트로 만들었다.
그래서 해당 컴포넌트를 클라이언트 컴포넌트에서 재사용하고자하니 계속해서 오류가 났던 것이다..

그래서 처음엔 Supense로 해당 컴포넌트를 감싸고 사용했음..ㅋㅋ
해당 방법은 근본적으로 Next가 지향하는 방식이 아니기에 결국엔 컴포넌트를 분리해서 비동기 처리 로직을 React hook에서 처리하도록 변경했다.

아마 알기론 이런 부분이 다음 Next 버전에서 변경되는 것으로 알고 있는데,
이후에 확인하고 다시 분석글을 작성해볼 것이다!

profile
사용자와 소통하는 프론트엔드 개발자

0개의 댓글