렌더링 방식으로 보는 next14 app router
csr 방식
csr 방식은 비어있는 html 파일이 먼저 서빙되고, script 태그를 통해 연결된 리액트 jsx 번들링 파일이 js 파일로 서빙되면서 화면이 그려지게 된다. 그렇기 때문에 유저는 js 파일이 모두 불러와지기 전엔 빈 화면을 봐야하기 때문에 초기로딩속도가 느린 방식이다. js 파일이 모두 불러와진 후, 브라우저에서 react 컴포넌트를 읽어서 가상 dom을 생성하고, 가상 dom을 통해 리얼 dom을 생성하여 화면에 보여지기 때문에 클라이언트 사이드 렌더링 즉 csr이 된다.
ssr 방식
page router
ssr 방식은 먼저 서버에서 react 코드를 바탕으로 html을 생성하고 서빙해서 컨텐츠들이 구성 된 화면을 보여준다. 이 때문에 초기로딩속도가 빠르다고 볼 수 있다. 하지만 이 때, react로 작성된 js 파일은 넘어오지 않은 상태이기 때문에 웹과 유저는 상호작용 할 수 없는 상태다. 이후 js 파일이 넘어오고, html 코드를 react화, 즉 하이드레이션 작업이 이루어 진다. 하이드레이션 작업이 끝나면 리액트 컴포넌트가 생성되고, 그 이후에는 csr 방식으로 화면이 업데이트 된다.
app router
13버전에서부터 app router라는 방식이 새로 업데이트 되었다. 기존 page router에서의 ssr 방식에서는 js 파일이 넘어오지 않으면 하이드레이션이 일어나지 않고, 유저는 아무런 상호작용을 할 수 없는 페이지에 머무는 시간이 길어지기 때문에 이탈율이 늘어날 수 있다. 이런 문제를 해결하기 위해서 streaming server rendering, partial hydration 등의 개념을 사용하는데, js 파일의 번들링을 나눠서 유의미한, 즉 유저가 클릭한 부분이라던지, 먼저 생성된 html 요소에 대한 번들링을 먼저 진행하고 더 작은 단위로 나눠 하이드레이션을 진행한다. 하이드레이션을 진행하고 마지막엔 하나로 합쳐진 js파일은 다시 csr 방식으로 화면 업데이트가 진행된다. 이를 통해 유저는 더 빠르게 웹과 상호작용 할 수 있다.
서버 컴포넌트와 클라이언트 컴포넌트
서버 컴포넌트
서버 컴포넌트는 데이터 fetching 과 서버와 직접적 접근이 가능하기 때문에 민감한 정보에 접근하더라도, 서버에서 접근하고 그 내용을 바탕으로 정적인 html 파일을 서빙하기 때문에 정보가 클라이언트로 새어나오지 않고, 서버에서는 큰 작업이라고 하더라도 클라이언트에서는 불필요한 js 파일을 서빙하지 않아도 된다.
클라이언트 컴포넌트
클라이언트 컴포넌트는 유저의 이벤트를 받을 수 있는 컴포넌트다. 또한, useState와 같은 상태관리, useEffect와 같은 라이프 사이클 함수는 클라이언트 컴포넌트에서만 사용 할 수 있다. 리액트에서는 모든 컴포넌트가 클라이언트 컴포넌트인데, next는 기본적으로 모든 컴포넌트는 서버 컴포넌트가 된다. 그래서 최상단에 ‘use client’라는 코드를 적어 해당 컴포넌트가 클라이언트 컴포넌트 임을 알려야한다.
서버 컴포넌트는 작성된 그 상태로 바로 렌더링이 될 것이고, 클라이언트 컴포넌트는 상태에 따른 화면의 변화가 있기 때문에 하이드레이션 과정을 거친다고 보면 된다.
적용 예시
api 호출이 2초가 걸리는 서버 컴포넌트가 있다고 하면, loading.tsx 파일을 생성해서 2초의 로딩 시간동안 띄울 수 있는 컴포넌트를 만들 수 있다. 이 때, loading 스피너를 react-spinner로 만들었는데, spinner가 움직이지 않고 초기 html + css 상태로만 남아있다. 이는, react-spinner가 내부적으로는 useState 같은 리액트 상태로 만들어졌기 때문에 기본적으로 모든 컴포넌트가 서버 컴포넌트로 생성되는 next의 특성 상, 리액트 코드가 작성 된 js 파일이 서빙되지 않아서 생기는 문제로, 이런 경우에 loading.tsx 파일 최상단에 “use client” 지시어를 사용해 클라이언트 컴포넌트로 전환해서 바로 js 파일을 서빙할 수 있도록 구현할 수 있다.
만약 이 loading 스피너를 서버 컴포넌트로 활용해야한다고 하면, js 없이 css로만 구현해서 className을 주면 구현할 수 있다.
'TIL' 카테고리의 다른 글
2024-04-24 TIL (0) | 2024.04.24 |
---|---|
2024-04-23 TIL (0) | 2024.04.24 |
2024-04-22 TIL (0) | 2024.04.23 |
2024-04-17 TIL (0) | 2024.04.23 |
2024-04-16 TIL (0) | 2024.04.23 |