기존에 무엇이 문제였나?
흔히들 React같은 SPA에 대한 문제를 언급할때 단골처럼 나오는 몇가지 문제가 존재합니다.
- 초기 렌더링이 오래걸린다 / 초기 렌더링시에 빈화면이 보인다 / SEO 친화적이지 않다 ... 등등
그러면 우선 왜? 저런 문제가 발생하는지를 알면 좋을거같습니다.
왜 SPA는 빈화면이 노출되는가
리액트같은 SPA의 동작방식은 간단히 말하면
- 서버에 요청 -> 서버에서 진입점등이 포함된 아주 간단한 html 응답
- 클라이언트에서 html 파싱 -> <script> 태그등을 만나면 js 번들 요청
- html 파싱 완료 DOM 구축 -> 화면 표시 -> 근데 표시할게 없음 (보통
만 존재하므로,,) - js 번들 도착 -> js를 이용하여 진입점으로부터 렌더링 -> 화면 표시 완료
- 이제부터는 서버에게 별도 요청없이 js를 이용하여 화면을 렌더링 -> 빠름
여기서 문제는 3 ~ 4번 과정입니다.
js번들이 도착해야하만 화면이 표시되고 인터렉티브한 동작이 가능해집니다.
근데 만약에 js번들이 매우 크다면? -> 빈화면 노출시간은 길어질것입니다.
그러면 SSR을 이용할까?
리액트를 SSR을 이용해서 렌더링하면 위의 모든 문제가 해결될까요?
- 서버에 요청 -> 서버에서 초기 html을 만들어서 클라이언트로 전송
- 클라이언트에서 html 파싱 -> <script> 태그등을 만나면 js 번들 요청
- html 파싱 완료 DOM 구축 -> 화면 표시 -> 완성된 화면이 표시됨
- js 번들 도착 -> 하이드레이션 -> 인터렉티브한 동작 가능
이 과정만 보면 SSR을 도입하면 모든 문제가 해결되어보입니다.
근데 4번에 위에서는 없던 하나의 과정이 포함되어있습니다. => hydration
하이드레이션이란: 정적 HTML을 리액트 애플리케이션으로 복구 시키는 과정
이 말은 즉, 하이드레이션 이전까지는 일종의 먹통 현상으로 유저는 느낄수있게됩니다.
분명 화면은 다 그려졌는데, 버튼을 눌러도 아무런 반응이 없는것처럼,,
정리
- 처음 문제는 "빈화면 노출시간이 길다"였습니다. -> 이를 SSR를 활용하여 해결하였습니다.
- 하지만 SSR로 전환해도 여전히 JS번들 도착 전까지는 유저의 경험성이 낮습니다 (일종의 먹통현상)
여기까지 보면 문제의 근본적인 원인이 보입니다. => JS 번들입니다.
어떻게 고민했나?
react, vercel팀도 이를 주요 문제로 본거같고, 이를 해결하는걸 과제로 잡은거같습니다.
심지어는 Zero-Bundle-Size 라는 표현까지 사용합니다.
즉 이들의 목표는 js 번들 사이즈를 최소화하여 위에서 나타난 문제를 해결하겠다라고 보입니다.
또한 이들은 기존 전통적인 수화 방식에도 약간의 문제점을 말하며 이를 개선한다는(지금은 개선되었죠) 글도 작성한적이 있습니다. 참고
정리하면 "근복적인 문제인 JS번들 사이즈를 줄여 하이드레이션 부담을 낮추겠다"로 보입니다.
어떻게 해결했나?
해결책은 간단하게 접근한거같습니다 (다만 직접 React + SSR 구현해보신분들은 아시겠지만,, 아래 내용을 직접 구현하려한다면(next.js 사용하지 않고) 매우 복잡한 과정이긴합니다,,)
서버에서 렌더링 가능한 (클라이언트 측 로직이 없는) 컴포넌트는 서버에서 렌더링해서 클라이언트로 전송하고 => 이러면 클라이언트측에서 이를 렌더링하는 부담이 적어짐
클라이언트 컴포넌트는 기존 그대로 가져가는 방법입니다.
- 이러면 기존에 모든 컴포넌트를 하이드레이션해야했던 것이 -> 클라이언트 컴포넌트만 하이드레이션하면 되게됩니다.
- 서버에서 렌더링된 컴포넌트는 클라이언트로 전송되는 js번들에 포함되지 않습니다 -> js 번들 사이즈가 감소합니다.
그래서 현업에서 쓸꺼냐?
지금까지의 문제 - 해결 - 성과를 현업에 똑같이 대입해서 예측해보면 사용할지 말지가 가늠이될거같습니다.
- 첫페이지 로딩이 느린 이슈가 존재하는지? -> SSR 내지는 RSC 활용
- SSR 사용중인데 일종의 먹통 현상이 길어서 사용자 경험이 낮은지? -> RSC 활용
참고
당연히 도입여부에 고려되어야할 부분은 훨씬 많지만 (비용, 학습곡선,,,,) 저는 이렇게 특정 주제만 잡아서 한번 작성해보았습니다.
'NextJs' 카테고리의 다른 글
[NextJs] 서버 액션을 사용하면 클라이언트 구성 요소가 서버에서 실행되는 비동기 함수를 호출할 수 있습니다 (0) | 2024.09.22 |
---|---|
[NextJs] Streaming을 이용하여 최대한 빠르게 컨텐츠를 표시할 수 있습니다 (0) | 2024.09.19 |
[NextJs] 서버 렌더링 vs 클라이언트 렌더링 (2) | 2024.09.17 |