해결된 질문
23.11.16 11:28 작성
·
1.3K
3
SSR 방식에 서버 컴포넌트와 클라이언트 컴포넌트를 둘 다 적절히 사용하는 것인가요??
서버 컴포넌트는 데이터 페칭, 보안, 캐싱, JS 번들크기 감소와 같은 장점이 있고 event와 hook을 사용하지 못한다는 특징도 이야기해주셨는데, 그렇다면 데이터를 받아서(페칭해서) 클라이언트 컴포넌트에 데이터를 뿌려주는 느낌으로 조합해서 사용하는 건가요??
서버컴포넌트는 event를 사용하지 않으므로, TTI를 개선하기 위해 나온 개념은 아닌거죠???
답변 5
3
2023. 11. 16. 19:59
종민님, 안녕하세요! 질문 남겨주셔서 감사합니다.
1. SSR 방식에 서버 컴포넌트와 클라이언트 컴포넌트를 둘 다 적절히 사용하는 것인가요??
SSR 방식은 서버 컴포넌트와 다른 방식입니다. 서버에서 컴포넌트를 렌더링한다는 점에서는 동일하지만 렌더링의 결과값과 동작 방식이 다릅니다.
SSR은 Prerendering의 방식으로 서버에서 HTML을 만들어냅니다. 이후에 클라이언트로 전달된 JS 번들 파일과 수화되는 과정을 거쳐 React 컴포넌트로 사용됩니다. 기존의 React 컴포넌트이며 이를 클라이언트 컴포넌트라고 부릅니다.
서버 컴포넌트는 JSON과 유사한 형태가 만들어집니다. 그 자체로 React 컴포넌트이기에 별도의 JS 번들 파일 없이 브라우저에서 컴포넌트로 사용됩니다. 새로운 컴포넌트이고 React Server Component, RSC라고 부릅니다.
두 가지를 함께 사용하는 경우는 서버 컴포넌트가 Children 요소로 클라이언트 컴포넌트에게 전달되는 경우일 것 같아요. 이때 모든 컴포넌트가 서버에서 렌더링되어 브라우저로 전달됩니다. 이후의 동작은 클라이언트 컴포넌트와 서버 컴포넌트가 다르지만 모두 서버에서 렌더링 되어 HTML, JSON 형태로 브라우저에 전달됩니다. 이러한 특성을 기억해서 알맞게 적절히 사용하는 것이 옳은 사용 방법이 될 수 있을 것 같습니다.
2. 서버 컴포넌트는 데이터 페칭, 보안, 캐싱, JS 번들크기 감소와 같은 장점이 있고 event와 hook을 사용하지 못한다는 특징도 이야기해주셨는데, 그렇다면 데이터를 받아서(페칭해서) 클라이언트 컴포넌트에 데이터를 뿌려주는 느낌으로 조합해서 사용하는 건가요??
"클라이언트 컴포넌트에 데이터를 뿌려주는 느낌"이라는 표현이 정확하게 이해가 되진 않았지만 나름의 해석을 붙여 답변드려볼게요!
서버 컴포넌트가 클라이언트 컴포넌트에 전달하는 데이터는 없고 그 자체로 컴포넌트의 역할을 합니다. 다만 앞선 답변에서처럼 Children 요소로 활용된다면 어떤 점에선 데이터를 전달한다고 볼 수도 있을 것 같습니다. 쉽게 표현하자면 클라이언트 컴포넌트의 구성 요소 중 하나로 서버 컴포넌트를 끼워 넣을 수 있다고 봐도 좋을 것 같아요.
서버컴포넌트는 event를 사용하지 않으므로, TTI를 개선하기 위해 나온 개념은 아닌거죠???
말씀주신 것처럼 서버 컴포넌트는 이벤트를 사용할 수 없기 때문에 컴포넌트 그 자체로 TTI에 직접 영향을 주진 못할 수 있습니다. 하지만 생각해보면 JS 번들 크기를 줄이는데 도움을 주기 때문에 전체적인 성능 개선에 영향을 줍니다. 그 결과 TTI에도 긍정적인 영향을 줄 수 있습니다.
애초에 서버 컴포넌트가 나온 이유에 대해 간단히 설명드려보겠습니다. 서버에서 미리 렌더링하는 Prerendering의 경우 페이지 단위로만 SSR, SSG를 수행할 수 있었어요. 서버 컴포넌트는 페이지 단위가 아닌 컴포넌트 단위로 서버에서 렌더링할 수 있도록 하기 위한 고민 끝에 나온 개념입니다. 그 결과 앞서 답변 드린 것처럼 클라이언트 컴포넌트와 혼용해서 쓸 수 있는 새로운 방식이 가능해진 것입니다.
관련해서 읽어보시면 도움될만한 글을 남겨두겠습니다! 제가 참고한 내용을 인용해뒀습니다.
Making Sense of React Server Components - Specifying client components
As a general rule, if a component can be a Server Component, it should be a Server Component. Server Components tend to be simpler and easier to reason about. There's also a performance benefit: because Server Components don't run on the client, their code isn't included in our JavaScript bundles. One of the benefits of the React Server Components paradigm is that it has the potential to improve the Page Interactive (TTI) metric.
일반적으로 컴포넌트가 서버 컴포넌트가 될 수 있다면 서버 컴포넌트가 되어야 합니다. 서버 컴포넌트는 더 간단하고 추론하기 쉬운 경향이 있습니다. 서버 컴포넌트는 클라이언트에서 실행되지 않기 때문에 자바스크립트 번들에 코드가 포함되지 않는다는 성능상의 이점도 있습니다. React 서버 컴포넌트 패러다임의 장점 중 하나는 페이지 인터랙티브 (TTI) 지표를 개선할 수 있는 잠재력이 있다는 것입니다.
많은 분들이 혼란스러워하는 부분이라 종민님의 질문이 다른 수강생분들께 도움이 되었을 것 같아요.
질문 주셔서 감사합니다. 다른 질문도 언제든 환영입니다! 편하게 남겨주세요 😃
2023. 11. 17. 09:08
그렇다면 클라이언트 컴포넌트는 결국 prerendering하던 방식을 그대로 사용하는 것이며 렌더링은 클라이언트에서 되어지고,
네, 클라이언트 컴포넌트는 Prerendering도 가능한 기존의 React 컴포넌트라고 이해하시면 될거 같아요.
서버 컴포넌트는 부분적인 hydration 방식을 통해서 React 컴포넌트가 되어지며 렌더링이 서버에서 되어지는 건가요??
서버 컴포넌트는 Hydration 단계가 없습니다. Hydration은 HTML 코드가 React 컴포넌트로 인식되도록 JavaScript 코드와 매칭시키는 단계인데 서버 컴포넌트는 서버에서 내려올 때 RSC Payload라는 일종의 JSON으로 전달되며 곧장 React 컴포넌트로 사용될 수 있습니다.
그럼 공식 문서에서는 왜 클라이언트 컴포넌트가 트리의 끝에 있으면 좋다고 설명되어진 건가요??
이 부분은 제가 답변을 보고 오해하셨을 거 같아요. "클라이언트 컴포넌트의 구성 요소 중 하나로 서버 컴포넌트를 끼워 넣을 수 있다"라고 답변 드린 부분 때문일 거 같습니다.
말씀주신 것처럼 공식 문서에서 클라이언트 컴포넌트를 트리의 끝에 보내라고 권합니다. 이 역시 서버 컴포넌트와 클라이언트 컴포넌트를 조합할 수 있는 방법입니다. 클라이언트 컴포넌트를 트리의 끝에 두라는 말은 서버 컴포넌트를 최대한 활용하기 위한 권장 사항이라고 이해하시면 좋을거 같아요.
클라이언트 컴포넌트가 트리의 상위에 있으면 하위에 있는 컴포넌트는 자식 요소로 전달하지 않는 이상 서버 컴포넌트를 활용하기 어렵습니다. 때문에 가능하면 클라이언트 컴포넌트를 트리의 끝으로 두려고 노력해야 앱 전체에서 서버 컴포넌트의 비중을 늘릴 수 있습니다. 그게 결국 번들 크기의 감소로 이어져서 전체적인 성능 향상에 도움이 된다고 보는 것이고요.
제가 질문을 잘 이해한 게 맞는지 모르겠네요. 답변이 되셨는지 알려주세요 😀
2023. 11. 17. 09:22
아 어느정도 틀이 보이는 것 같습니다!
즉, 서버 컴포넌트는 서버에서 렌더링 되어진 React 컴포넌트이고, 클라이언트 컴포넌트는 prerender이 가능한 기존의 컴포넌트 이므로 둘을 적절히 조합해서 사용해야 하는 거군요
서버 컴포넌트는 서버에서 미리 렌더링되어 졌기 때문에 전체적인 JS 번들 크기가 감소하므로 First View를 개선할 수 있으며 TTI에도 간접적인 영향을 줄 수 있다라고 보면 될까요??
2023. 11. 17. 10:07
즉, 서버 컴포넌트는 서버에서 렌더링 되어진 React 컴포넌트이고, 클라이언트 컴포넌트는 prerender이 가능한 기존의 컴포넌트 이므로 둘을 적절히 조합해서 사용해야 하는 거군요
네! 맞습니다
서버 컴포넌트는 서버에서 미리 렌더링되어 졌기 때문에 전체적인 JS 번들 크기가 감소하므로 First View를 개선할 수 있으며 TTI에도 간접적인 영향을 줄 수 있다라고 보면 될까요??
정확합니다 😁
2023. 11. 17. 12:57
종민님, 이해가 되셨다니 다행입니다 🙂
남겨주신 질문보면 앞으로 더 잘하실 거 같아요! 응원하겠습니다.
좋게 봐주셔서 감사합니다! 다음 강의도 잘 준비해볼게요!
2
1
1
2024. 01. 20. 15:18
네트워크탭을 확인해봤을 때, Next.js의 첫번째 요청이나 새로고침시에는 pre-rendering한 HTML 파일을 받아오는데, 그 이후부터는 RSC Payload 형태의 JSON 데이터만 받아오게 되는데 이것이 Next.js가 SPA라는 뜻일까요??
hard navigate시에만 HTML을 받아오게 되고, soft navigate시에는 JSON 형태의 데이터를 받아오게 되는게 맞을까요 (즉, SPA의 동작을 하게 되는건가요??)
2024. 01. 20. 16:39
종민님, 좋은 질문 감사합니다.
우선 해당 질문에 대한 답변은 공식 문서에 나와있습니다! (공식 문서: Rendering > Client Components > Subsequent Navigations)
Subsequent Navigations
On subsequent navigations, Client Components are rendered entirely on the client, without the server-rendered HTML.
This means the Client Component JavaScript bundle is downloaded and parsed. Once the bundle is ready, React will use the RSC Payload to reconcile the Client and Server Component trees, and update the DOM.
요약하자면 최초의 페이지 렌더링은 HTML를 서버에서 생성하지만 이후에는 클라이언트에 있는 자바스크립트 코드로 브라우저에서 전적으로 렌더링됩니다. 말씀주신 것처럼 SPA처럼 동작한다고 볼 수 있습니다.
질문 남겨주실 때마다 열심히 하고 계신 게 느껴집니다!
앞으로도 좋은 질문 부탁드리겠습니다. 감사합니다!
2024. 01. 20. 17:02
공식 문서를 읽어서 한 번 알고 넘어가는 것보다 직접 네트워크 탭을 열어서 사실인지 확인하는 과정이 더 중요하다고 생각합니다. 정말 멋지십니다! 앞으로도 응원하겠습니다!
1
2024. 01. 15. 17:31
선생님 추가로 질의드릴 부분이 생겼습니다!
네트워크 탭을 통해 라우팅으로 이동하게 되면 RSC Payload를 응답으로 받는다는 사실을 알게 되었습니다.
Server Component는 서버에서 실행되었기 때문에 RSC Payload 상에 데이터가 있지만 Client Component는 참조의 형태로 남아있는 것으로 이해했는데, 그렇다면 Client Component는 렌더링 시에 hydration 작업이 별도로 이뤄지는 것인가요??
2024. 01. 15. 22:36
종민님, 또 한 단계 성장하셨네요!
확인하신 것처럼 서버 컴포넌트는 RSC Payload로 브라우저에 전달됩니다. 반면 클라이언트 컴포넌트는 HTML로 전달되어 Hydration 단계를 거치게 됩니다.
관련해서 최근에 비슷한 질문을 남겨주신 사례가 있어서 공유드려요!
한 번 읽어보시고 궁금한 점 있으시면 다시 질문 주세요.
https://www.inflearn.com/questions/1138436
좋은 질문 남겨주셔서 감사합니다!
2023. 11. 17. 00:02
친절한 답변 감사드립니다!
그렇다면 클라이언트 컴포넌트는 결국 prerendering하던 방식을 그대로 사용하는 것이며 렌더링은 클라이언트에서 되어지고, 서버 컴포넌트는 부분적인 hydration 방식을 통해서 React 컴포넌트가 되어지며 렌더링이 서버에서 되어지는 건가요??
그럼 공식 문서에서는 왜 클라이언트 컴포넌트가 트리의 끝에 있으면 좋다고 설명되어진 건가요??