CSR, SSR ๊ทธ๋ฆฌ๊ณ Pre-rendering
Client Side Rendering, Server Side Rendering ๊ทธ๋ฆฌ๊ณ Pre-rendering ์ ๋ํด ๊ณต๋ถํด๋ดค์ต๋๋ค.

๐๐ป ๋ค์ด๊ฐ๋ฉฐ
์ฌ์ค Next.js ์์์ styled-component ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ด๋ จํด์ ์ฌ๊ฐํ ๊ณ ๋ฏผ์ ๋น ์ ธ์์์ด์ ์ด ๋ถ๋ถ์ ๋ํ ํธ๋ฌ๋ธ ์ํ ์ ์์ฑํ๋ ๋์คใ ใ ใ ๋ํฌ ํธ๊น๊ธฐ๋ก CSR, SSR, Pre-rendering ์ ๋ํด ์ ๋๋ก ์๊ณ ๊ฐ์ผ๊ฒ ๋จ ์๊ฐ์ด ๋ค์โฆ๋ค ํํ
React ๊ณต๋ถ๋ฅผ ์ฒ์ ์์ํ ๋ ํด๋น ๋ถ๋ถ์ ๋ํด ์ถฉ๋ถํ ๊ณต๋ถํ๋ค๊ณ ์๊ฐ์ ํ์๋๋ฐ, ๋ง์ ์ด ๋ถ๋ถ์ ๋ํด ์ ๋๋ก ์ค๋ช ํ ์ ์๋๊ฐ? ๋ฅผ ์ค์ค๋ก ์ง๋ฌธํด๋ณด๋ ๊ทธ๋ ์ง ๋ชปํ๊ธฐ์.. ์ด๋ฒ ๊ธฐํ์ ์ ๋๋ก ํด์ผ๊ฒ ๋ค๋ ์๊ฐ์ ๋ค์ ๊ณต๋ถ๋ฅผ ํด๋ดค๋ค.
๐ฉ๐ปโ๐ป Client Side Rendering

์ถ์ฒ : https://www.blog.duomly.com/client-side-rendering-vs-server-side-rendering-vs-prerendering/
โ๏ธ CSR process
์ ์ ๊ฐ ์น ์ฌ์ดํธ์ ์ง์ (request)ํ๋ค.
CDN ์ ์ต์ํ์ HTML ํ์ผ์ ๋ค์ด๋ก๋(response) ํ๋ค.
index.html:script,meta,link๋ฑ์ ํ๊ทธ๋ฅผ ํฌํจํ๋ฉฐ ๋น ์ปจํ ์ธ ๋ฅผ ๋ด๊ณ ์๋ค.
๋ธ๋ผ์ฐ์ ๋
index.html์ ์๋ JavaScript ๋ฒ๋ค ํ์ผ์ ๋ค์ด๋ก๋ ํ๋ค.api ์์ฒญ์ ์ํํด ๋์ ์ปจํ ์ธ ๋ฅผ ๊ฐ์ ธ์ ํ์ฑํ๊ณ ์ต์ข ์ปจํ ์ธ ๋ฅผ ๋ ๋๋งํ๋ค.
์ ์ ๊ฐ ํ์ด์ง๋ฅผ ์ด๋ํ๋ค๋ฉด ์๋ฒ์ ์ถ๊ฐ html ํ์ผ์ ์์ฒญํ์ง ์๊ณ ์ด๋ฏธ ๋ฐ์ javaScript ๋ฅผ ์ด์ฉํด ๋ ๋๋งํ๋ค.
๐ Server Side Rendering

์ถ์ฒ : https://www.blog.duomly.com/client-side-rendering-vs-server-side-rendering-vs-prerendering/
๐ SSR Process
์ ์ ๊ฐ ์น ์ฌ์ดํธ์ ์ง์ (request)ํ๋ค.
CDN ์ ๋ฆฌ์์ค๋ฅผ ํ์ธํ๊ณ ํ์ด์ง ๋ด์ ์๋ ์๋ฒ์ธก ์คํฌ๋ฆฝํธ๋ฅผ ์คํํด HTML ์ปจํ ์ธ ๋ฅผ ์ปดํ์ผ ๋ฐ ์ค๋นํ๋ค.
์ปดํ์ผ๋ HTML ์ ์ถ๊ฐ ๋ ๋๋ง ๋ฐ ํ์๋ฅผ ์ํด ํด๋ผ์ด์ธํธ ๋ธ๋ผ์ฐ์ ๋ก ์ ์ก๋๋ค.(response)
๋ธ๋ผ์ฐ์ ๋ HTML ์ ๋ค์ด๋ก๋ํ๊ณ ์ต์ข ์ฌ์ฉ์๊ฐ ์ฌ์ดํธ๋ฅผ ๋ณผ ์ ์๊ฒ ํ๋ค.
๋ธ๋ผ์ฐ์ ๋ JavaScript ๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์คํํ๋ฉฐ ํ์ด์ง๋ฅผ interactive ํ๊ฒ ๋ง๋ ๋ค.
์ ์ ๊ฐ ํ์ด์ง๋ฅผ ์ด๋ํ๋ฉด ์ ๋์์ด ๋ฐ๋ณต๋๋ค.
๐คฌ Uncanny Valley

์ถ์ฒ: https://crystallize.com/blog/frontend-performance-react-ssr-and-the-uncanny-valley
SSR ๋ฐฉ์์ผ๋ก ํ๋ฉด์ ๋ ๋๋ง ํ์ ๋, View ๊ฐ ๊ทธ๋ ค์ง ํ JavaScript ๊ฐ ๋ค์ด๋ก๋๋ ๋ ๊น์ง ์ธํฐ๋์ ์ด ์ผ์ด๋ ์๊ฐ ์๋ค. ๋ง์ฝ ๊ทธ ์ฌ์ด ๋ค์ด๋ก๋๊ฐ ์๋ฃ๋๋ฉด ๊ทธ ๋๋ถํฐ ์ ์ ๋ ์ฌ์ดํธ์ ์ธํฐ๋์ ์ ํ ์ ์๋๋ฐ, ๋ทฐ๋ ์์ง๋ง ์ธํฐ๋์ ์ด ์๋๋ ๊ตฌ๊ฐ์ โUncanny Valley(๋ถ์พํ ๊ณจ์ง๊ธฐ)โ๋ผ๊ณ ํ๋ค.
๐ค CSR vs SSR
CSR ๊ณผ SSR ์ ๋ ๋๋ง ๋ฐฉ์์์์ ์ฐจ์ด์ ์ ๊ฒฐ๊ตญ ๋ ๋๋ง์ ์๋ฒ์ธก์์ ๋ด๋นํ๋์ง, ํด๋ผ์ด์ธํธ์ธก์์ ๋ด๋นํ๋์ง์ด๋ค. CSR ์ ์ต์ํ์ html ํ์ผ์ ๋ฐ์ ํ, ์ฑ์์ ์ฌ์ฉ๋๋ ๋ชจ๋ js ์ฝ๋๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ DOM ์์๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ด๋ผ๋ฉด, SSR ์ ํ์ด์ง์ ๋ํ ๋ชจ๋ ๊ฒ๋ค์ ์๋ฒ์ธก์์ ๋ค์ด๋ก๋ ๋ฐ์ ๊ทธ๋ ค๋ธ๋ค.
CSR ์ ๊ฒฝ์ฐ๋ ์ฒซ ์ง์ ์ ๋ชจ๋ js ์ฝ๋๋ฅผ ๋ก๋ํด์ผํ๋ฏ๋ก ์ด๊ธฐ ๋ ๋๋ง ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฐ๋ค. ํ์ง๋ง, ์ดํ์๋ ์ถ๊ฐ์ ์ธ ๋ก๋๊ฐ ํ์ํ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ๋ถ๋๋ฌ์ด ์ ์ ๊ฒฝํ์ ์ ๊ณตํ๋ค. ํ๋ฉด ๋ด์์ ๋ค๋ฅธ ํ์ด์ง๋ก ์ด๋ํ๋ ๊ฒฝ์ฐ๋ผ๊ณ ํ๋๋ผ๋, html ์์ค๋ฅผ ์๋ฒ์์ ๋ฐ๋ ๋ฐฉ์์ด ์๋ ํด๋ผ์ด์ธํธ ์ธก์์ ์ฒ๋ฆฌํ๋ฏ๋ก ํจ์ฌ ๋น ๋ฅธ ํธ์ด๋ค.
๊ทธ๋ฌ๋ ์ฒ์ ๋ค์ด๋ก๋ ๋ฐ๋ javaScript ๋ฒ๋ค ์ฌ์ด์ฆ๊ฐ ํด ๊ฒฝ์ฐ์๋ ์ด๊ธฐ ๋ ๋๋ง ์๋๊ฐ ํ์ ํ ๋๋ ค์ง ์ ์์ผ๋ฏ๋ก ์ด์ ๋ํ ์ต์ ํ ๋ฐฉ๋ฒ์ ๋ํด ๊ณ์ ๊ณ ๋ฏผํด์ผํ๋ค. ๋ํ html ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๋ ๋ฐฉ์์ด ์๋๊ณ ์ ์ ์ ์์ฒญ์ ๋ฐ๋ผ ์์ฑ๋๋ฏ๋ก SEO(serach engine optimization : ๊ฒ์ ์์ง ์ต์ ํ) ๋์์ด ์ด๋ ค์ด ํธ์ด๋ค.
SSR ์ ๊ฒฝ์ฐ๋ CSR์์ ๋ฐ์ํ๋ ์ด๊ธฐ ๋ ๋๋ง ์๋, ๋ฒ๋ค ์ฌ์ด์ฆ, SEO ๋ฑ์ ๋ฌธ์ ์ ๊ฐ์ ์ ์ํด ๊ณผ๊ฑฐ์ static site ๋ก ๋์๊ฐ ๋ฐฉ์์ด๋ค. CSR ๊ณผ๋ ๋ค๋ฅด๊ฒ ์๋ฒ์์ html ์ ๋ง๋ค์ด ์ ๊ณตํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ SEO ์ต์ ํ๊ฐ ์ ์ด๋ฃจ์ด์ง๋ฉฐ ๊ฐ ํ์ด์ง๋ณ๋ก ๋ค์ด์ด ๋๋ฏ๋ก ์ด๊ธฐ ๋ ๋๋ง ์๋๋ ๋น ๋ฅธ ํธ์ด๋ค.
๐คจ CSR ๊ณผ SSR ์ ํ์ ์ด๋ค ๊ฒ์ ๊ธฐ์ค์ผ๋ก ์ก์ผ๋ฉด ์ข์๊น?
SSR
๋๋ฆฐ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ ๋ (SSR์ ๊ฐ ํ์ด์ง๋ณ๋ก ์๋ต๊ฐ์ ๋ฐ์์ค๊ธฐ ๋๋ฌธ!)
SEO ์ต์ ํ๋ฅผ ํ์๋ก ํ ๋
๋น ๋ฅธ ์ด๊ธฐ ๋ ๋๋ง์ ํ์๋ก ํ ๋
๋ฉ์ธ ์คํฌ๋ฆฝํธ๊ฐ ํฌ๊ณ ๋ก๋ฉ์ด ๋งค์ฐ ๋๋ฆด ๋
์น ์ฌ์ดํธ ๋ด์์ ์ํธ์์ฉ์ด ๋ณ๋ก ์์ ๋
CSR
๋คํธ์ํฌ๊ฐ ๋น ๋ฅผ ๋
์๋ฒ ์ฑ๋ฅ์ด ์ข์ง ์์ ๋
์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค์ผ ํ๋ ๋ฐ์ดํฐ์ ์์ด ๋ง์ ๋
๋ฉ์ธ ์คํฌ๋ฆฝํธ๊ฐ ๊ฐ๋ฒผ์ธ ๋
SEO ์ต์ ํ๊ฐ ์ค์ํ์ง ์์ ๋
์น ์ฌ์ดํธ ๋ด์์ ์ํธ์์ฉ์ด ๋ง์ ๋
๐ Pre-rendering

์ถ์ฒ : https://www.blog.duomly.com/client-side-rendering-vs-server-side-rendering-vs-prerendering/
Next.js ๊ณต์๋ฌธ์ ๋์ ๋ถ๋ฅผ ๋ณด๋ฉด ์๋์ ๊ฐ์ด ๋์์๋ค.
By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
๊ธฐ๋ณธ์ ์ผ๋ก Next.js ๋ ๋ชจ๋ ํ์ด์ง๋ฅผ pre-rendering ํ๋ค. ์ฌ๊ธฐ์ ๋งํ๋ pre-rendering ์ Next.js ๊ฐ client-side javascript ๋ก ๋ชจ๋ ์์ ์ ์ํํ๋ ๋์ , ๋ฏธ๋ฆฌ ๊ฐ ํ์ด์ง์ ๋ํด html ์ ๋ง๋ค์ด๋๋ ๊ฒ์ ์๋ฏธํ๋ค. pre-rendering ์ SEO ์์ ๋ ๋์ ํผํฌ๋จผ์ค๋ฅผ ๋ณด์ฌ์ค๋ค.
์ด๋ ๊ฒ ์์ฑ๋ html ์ ํ์ด์ง๊ฐ ๋ธ๋ผ์ฐ์ ์ ๋ก๋๋ ๋ ํด๋น JavaScript ์ฝ๋๊ฐ ๋์๊ฐ๊ณ ์์ ํ interactive page๊ฐ ๋๋๋ก ๋ง๋๋๋ฐ, ์ด๋ฅผ hydration์ด๋ผ๊ณ ํ๋ค.
Next.js ์์์ Server-side rendering ๊ณผ Static Generation ์ ๋ชจ๋ pre-rendering ๋ฐฉ์์ด๋ฉฐ ํ์ํ data fetching ๊ณผ HTML ๋ ๋๋ง์ด client ์ ๋ณด๋ด์ง๊ธฐ ์ ์ ์ด๋ฏธ ์ํ์ด ๋๋ค. ์ด๋ฅผ ํตํด์ client ๋ non-interactive ํ ํ์ด์ง๋ฅผ ๋น ๋ฅธ ์๊ฐ์ ์ ๋ฌ๋ฐ์ ์ ์์ผ๋ฉฐ, ์ปดํฌ๋ํธ์ ํ์ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋์ ๊ฐ์ interactive ํ ์์ฑ๋ค์ ๋ณ๋์ ๋ฒ๋ค๋ก ์ ๋ฌ์ ๋ฐ์์ client ์ธก์์ hydration ์ด ์ด๋ฃจ์ด์ง ๋ค์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ์น์ฑ์ด ๋๋ค.
๐ง๏ธ hydration
pre-rendering ๋ฐฉ์์ผ๋ก ๊ตฌ์ถ๋ ์ด๊ธฐ DOM์ ๋์ ์ธ ์ด๋ฒคํธ๊ฐ ์๋ ๋ฉ๋ง๋ฅธ ์ํ์ ๋ผ๋์ด๋ค. ์ด ๋ฉ๋ง๋ฅธ ๊ณณ์ ์๋ถ์ ๋ณด์ถฉํ๋, HTML ๊ณผ JavaScript ๋ฅผ ์๋ก ๋งค์นญ์์ผ ๋์ ์ธ ์น ์ฌ์ดํธ๋ฅผ ๋ธ๋ผ์ฐ์ ์ ๋ ๋๋ง ์ํค๋ ๊ธฐ์ ์ Hydration ์ด๋ผ๊ณ ํ๋ค. ์๋์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํ๋ฉด ๋ ์ดํด๊ฐ ์ฌ์ธ ๊ฒ์ด๋ค.

render() ํจ์์ hydrate() ํจ์๋ ๋น๊ต๋ฅผ ํด๋ณด์.
ReactDOM.render(element, container, [callback]);
// ์ ๊ณต๋ container ์ element ๋ฅผ ๋ ๋ํ๊ณ , component์ ๋ํ ์ฐธ์กฐ๋ฅผ ๋ฐํ
// ๊ธฐ์กด ์์์ ๋ฎ์ด์ฐ์ง ์๊ณ ๊ธฐ์กด DOM ๋
ธ๋์ ๊ตฌ์ฑ์์๋ฅผ Insert
ReactDOM.render() ํจ์๋ ํน์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธ๋์ธ ์ง์ ๋ DOM ์์ ํ์๋ก ์ฃผ์
ํด ๋ ๋๋ง์ ์ฒ๋ฆฌํด์ฃผ๋ ํจ์์ด๋ค. ๋ ๋๋ง์ด ์๋ฃ๋๋ฉด ํน์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ฝ ๋ฐฑ ํจ์๋ฅผ ์ธ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ๋ก ๋ฃ์ ์ ์๋ค.
ReactDOM.hydrate(element, container, [callback]);
// ๊ธฐ์กด ๋งํฌ์
์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ถ์ฌ์ฃผ๋ ๊ณผ์
ReactDOM.hydrate() ํจ์๋ ํน์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ธ ์ง์ ๋ DOM ์์์ ํ์๋ก hydrate ์ฒ๋ฆฌ๋ง ๋ด๋นํ๋ค. ๋ ๋๋ง์ ํตํด ์๋ก์ด ์น ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ DOM ์ ์์ฑํ๋ ๊ฒ์ด ์๋, ๊ธฐ์กด DOM Tree ์์ ํด๋นํ๋ DOM ์์๋ฅผ ์ฐพ์ ์ ํด์ง javascript ์์ฑ๋ค๋ง ๋ถ์ฐฉ์ํจ๋ค๋ ์๋ฏธ์ด๋ค.
๐ฅฒ ์ดํด๊ฐ ์ด๋ ค์ ๋ ๋ถ๋ถ,
CSR ๊ณผ SSR ์ ๋ ๋๋ง ๋ฐฉ์์ ์ฐจ์ด์ ์ ์ด์ผ๊ธฐํ๋ผ๊ณ ํ๋ฉด ๋๋ฌด๋ ๋ช ํํด์, ์ค๋ช ์ด ์ฌ์ ๋๋ฐ ์ฌ๊ธฐ์ Pre-rendering ๊ณผ SSR์ ์ฐจ์ด๋ ๋ฌด์์ธ์ง ์ฒ์์๋ ๋์ ํ ๋ค์ด์ค์ง ์์๋ค. ๊ฒฐ๊ตญ์ HTML ์ ์๋ฒ์์ ๊ทธ๋ ค์ฃผ๊ณ ์๋ต์ผ๋ก ๋ด๋ ค์ฃผ๋ฉด, ์ดํ์ JavaScript ์ฝ๋๊ฐ ๋๋ฉด์ ์ธํฐ๋ํฐ๋ธํ ์น์ฌ์ดํธ๊ฐ ๋๋ค๋๊ฒ ์๋๊ฐ? ์ถ์๊ธฐ์..
ํ์ง๋ง ์ด ๋๊ฐ์ง์ ์ฐจ์ด์ ์ด๋ผ๊ณ ํ๋ค๋ฉด JavaScript ์ฝ๋์ ๋ค์ด๋ก๋ ์์ ์ ์ฃผ๋ชฉํด์ผํ ๊ฒ ๊ฐ๋ค. ์๋ ๊ทธ๋ฆผ๋ค์ ๋น๊ตํ๋ฉด Pre-rendering ์ ๊ฒฝ์ฐ์๋ JavaScript ๋ ์๋ฒ์์ static HTML ์ ๋ณด๋ด์ฃผ๋ ์์ ์ ํจ๊ป ์ ์ก์ด ๋์ง๋ง, SSR์ ๊ฒฝ์ฐ์๋ HTML์ ํด๋ผ์ด์ธํธ ์ธก์ ๋ณด๋ด์ด ๋ ๋๋ง์ ๋๋ธ ์์ ์ JavaScript ๋ค์ด๋ก๋๊ฐ ์ด๋ฃจ์ด์ง๋ค.
ํ ๊ทธ๋ผ SSR์์์ Pre-rendering ์ผ๋ก Uncanny Valley ๋ฅผ ์ค์๋ค๊ณ ๋ณด๋ฉด๋๋๊ฑธ๊น..? Hoxy ์๋ชป๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ๋๊ธ๋ฌ์์ฃผ์ญ์ผ!


์ถ์ฒ : https://www.blog.duomly.com/client-side-rendering-vs-server-side-rendering-vs-prerendering/
๐ฉ๐ปโ๐พ ๋ง๋ฌด๋ฆฌ
์ฌ์ค ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ฉด์ ์ ๊ทธ๋ฅ ์ด๋ฐ๊ฒ ์๊ตฌ๋~ ํ๋ฉด์ ๋๊ฒผ๋ ๋ถ๋ถ๋ค์ ์ ๋๋ก ์ง์ ์ ์์ด์ ์ข์๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ค ์ด๊ฒ๋ค์ ๋ณด๊ธฐ ์ ์ ๊ฒช๊ณ ์๋ ๋ฌธ์ ์ ๋ํด์ ์กฐ๊ธ์ ๊ฐ์ด ์ข ์กํ ๊ฒ ๊ฐ์์ ์ผ๋ฅธ ๋ค์ ์ฐพ์๋ด์ผ๊ฒ ๋ค. ๋ด๊ฐ ์๊ฐํ๋ ๋ถ๋ถ์ด ๋ง๋์งโฆ! ๊ทธ๋ฆฌ๊ณ Next.js ์์์ ์ฌ๋ฌ๊ฐ์ง ๋ ๋๋ง ๋ฐฉ์๋ ์กฐ๋ง๊ฐ ์ ๋๋ก ์ ๋ฆฌ๋ฅผ ํด๋ด์ผ๊ฒ ๋ค. ์ค๋๋ ๊ณต๋ถํ ๊ฒ๋ค ํ๋ ์ง์ ๊ณ , ๋ ๊ฐ๊ฐ ์ถ๊ฐ๋์๋ค! ๐
![[์๊ฐ ์ดํธ๋ฃจ] 3์์ ํ๊ณ .](https://cdn.hashnode.com/res/hashnode/image/upload/v1711895194426/f6a22b40-ffd3-4b11-a25b-e1b040b11853.png)
![[์๊ฐ ์ดํธ๋ฃจ] 2์์ ํ๊ณ .](https://cdn.hashnode.com/res/hashnode/image/upload/v1709129901980/5a2af3c5-8f6e-4f07-9c4f-1b43bef27ae9.png)


![[์๊ฐ ์ดํธ๋ฃจ] 1์์ ํ๊ณ .](https://cdn.hashnode.com/res/hashnode/image/upload/v1706708547437/51af577d-21f9-4256-8939-95c577a58abc.jpeg)