์น์ฌ์ดํธ ์ฑ๋ฅ, SEO ๋ฐ ์ฌ์ฉ์ ๊ฒฝํ ํฅ์์ ์ํ React ์คํธ๋ฆฌ๋ฐ๊ณผ ์ ์ง์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR) ๊ธฐ์ ์ ํ๊ตฌํฉ๋๋ค. ๋ ๋น ๋ฅธ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ๊ณผ ํฅ์๋ ์ํธ์์ฉ์ ์ํ ์คํธ๋ฆฌ๋ฐ SSR ๊ตฌํ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
React ์คํธ๋ฆฌ๋ฐ: ์ต์ ํ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํ ์ ์ง์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง
์น ๊ฐ๋ฐ์ ์ธ๊ณ์์ ๋น ๋ฅด๊ณ ๋ฐ์์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ฌ์ฉ์๋ค์ ์น์ฌ์ดํธ๊ฐ ์ง์ฐ ์์ด ๋น ๋ฅด๊ฒ ๋ก๋๋๊ณ ์ํธ์์ฉํ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค. ์ฌ์ฉ์ ์ธํฐํ์ด์ค ๊ตฌ์ถ์ ์ํ ์ธ๊ธฐ ์๋ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ React๋ ์ด๋ฌํ ๊ณผ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์คํธ๋ฆฌ๋ฐ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ด๋ผ๋ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ React ์คํธ๋ฆฌ๋ฐ SSR์ ๊ฐ๋ ์ ๊น์ด ์๊ฒ ํ๊ตฌํ๊ณ , ๊ทธ ์ด์ , ๊ตฌํ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์น์ฌ์ดํธ ์ฑ๋ฅ ๋ฐ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฏธ์น๋ ์ํฅ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ด๋ ๋ฌด์์ธ๊ฐ?
๊ธฐ์กด ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง(CSR)์ ๋ธ๋ผ์ฐ์ ๊ฐ HTML, JavaScript ๋ฐ CSS ํ์ผ์ ๋ค์ด๋ก๋ํ ๋ค์ ํด๋ผ์ด์ธํธ ์ธก์์ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ ์ฐํ์ง๋ง, ์ด ๋ฐฉ์์ ์ฌ์ฉ์๊ฐ ๋ชจ๋ ๋ฆฌ์์ค๊ฐ ๋ค์ด๋ก๋๋๊ณ JavaScript๊ฐ ์คํ๋ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ์ฝํ ์ธ ๋ฅผ ๋ณผ ์ ์์ผ๋ฏ๋ก ์ด๊ธฐ ๋ ๋๋ง ์ง์ฐ์ ์ด๋ํ ์ ์์ต๋๋ค. ๋ฐ๋ฉด์ SSR์ React ์ปดํฌ๋ํธ๋ฅผ ์๋ฒ์์ ๋ ๋๋งํ๊ณ ์์ ํ ๋ ๋๋ง๋ HTML์ ํด๋ผ์ด์ธํธ์ ๋ณด๋ ๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ฆ์ ํ์๋ ์ ์๋ ์์ ํ ํ์ฑ๋ HTML์ ์์ ํ๋ฏ๋ก ๋ ๋น ๋ฅธ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ๊ฐ์ ธ์ต๋๋ค.
๊ธฐ์กด SSR์ ํ๊ณ
๊ธฐ์กด SSR์ CSR์ ๋นํด ์๋นํ ๊ฐ์ ์ ์ ๊ณตํ์ง๋ง, ๊ทธ ์์ฒด์ ํ๊ณ๊ฐ ์์ต๋๋ค. ๊ธฐ์กด SSR์์๋ ํด๋ผ์ด์ธํธ์ HTML์ด ์ ์ก๋๊ธฐ ์ ์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ฒ์์ ๋ ๋๋ง๋์ด์ผ ํฉ๋๋ค. ์ด๋ ํนํ ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ ์ข ์์ฑ์ ๊ฐ์ง ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ ๋ณ๋ชฉ ํ์์ด ๋ ์ ์์ต๋๋ค. ์ฒซ ๋ฐ์ดํธ ์๊ฐ(TTFB)์ด ๋์ ์ฌ์ฉ์์๊ฒ๋ ๋๋ฆฌ๊ฒ ๋๊ปด์ง ์ ์์ต๋๋ค.
React ์คํธ๋ฆฌ๋ฐ SSR์ ๋ฑ์ฅ: ์ ์ง์ ์ ๊ทผ ๋ฐฉ์
React ์คํธ๋ฆฌ๋ฐ SSR์ ์ ์ง์ ์ ๊ทผ ๋ฐฉ์์ ์ฑํํ์ฌ ๊ธฐ์กด SSR์ ํ๊ณ๋ฅผ ๊ทน๋ณตํฉ๋๋ค. ์คํธ๋ฆฌ๋ฐ SSR์ ์๋ฒ์์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ ๋๋ง๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ , ๋ ๋๋ง ํ๋ก์ธ์ค๋ฅผ ๋ ์์ ์ฒญํฌ๋ก ๋ถํดํ๊ณ ์ด ์ฒญํฌ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ ๋๋ก ํด๋ผ์ด์ธํธ์ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ธ๋ผ์ฐ์ ๋ ํจ์ฌ ๋ ์ผ์ฐ ์ฝํ ์ธ ๋ฅผ ํ์ํ๊ธฐ ์์ํ์ฌ ์ฒด๊ฐ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ TTFB๋ฅผ ์ค์ผ ์ ์์ต๋๋ค. ๋ง์น ๋ ์คํ ๋์ด ์์ฌ๋ฅผ ๋จ๊ณ๋ณ๋ก ์ค๋นํ๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํด๋ณด์ธ์. ์ ์ฒด ์์ฌ๊ฐ ํ ๋ฒ์ ์ค๋น๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ , ์ ํผํ์ด์ ๊ฐ ๋จผ์ ๋์ค๊ณ , ๊ทธ ๋ค์ ๋ฉ์ธ ์ฝ์ค, ๋ง์ง๋ง์ผ๋ก ๋์ ํธ๊ฐ ์ ๊ณต๋๋ ์์ ๋๋ค.
React ์คํธ๋ฆฌ๋ฐ SSR์ ์ด์
React ์คํธ๋ฆฌ๋ฐ SSR์ ์น์ฌ์ดํธ ์ฑ๋ฅ ๋ฐ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ค์ํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ๋ ๋น ๋ฅธ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ: HTML ์ฒญํฌ๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์คํธ๋ฆฌ๋ฐํจ์ผ๋ก์จ ๋ธ๋ผ์ฐ์ ๋ ํจ์ฌ ๋ ์ผ์ฐ ์ฝํ ์ธ ๋ฅผ ํ์ํ๊ธฐ ์์ํ์ฌ ์ฒด๊ฐ ๋ก๋ฉ ์๊ฐ์ ๋จ์ถํ๊ณ ์ฌ์ฉ์ ์ฐธ์ฌ๋๋ฅผ ํฅ์์ํต๋๋ค.
- ์ฒซ ๋ฐ์ดํธ ์๊ฐ(TTFB) ๊ฐ์ : ์คํธ๋ฆฌ๋ฐ SSR์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ ๋๋ง๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ด๊ธฐ HTML ์ฒญํฌ๊ฐ ์ค๋น๋๋ ์ฆ์ ์ ์กํ์ฌ TTFB๋ฅผ ์ค์ ๋๋ค.
- ํฅ์๋ ์ฌ์ฉ์ ๊ฒฝํ: ๋ ๋น ๋ฅธ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํต๋๋ค. ์ฌ์ฉ์๊ฐ ์ฝํ ์ธ ๊ฐ ๋ํ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ๋ ๋์ SEO: HTML์ด ์๋ฒ์์ ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฏ๋ก ๊ฒ์ ์์ง์ด ์ฝํ ์ธ ๋ฅผ ๋ ํจ๊ณผ์ ์ผ๋ก ํฌ๋กค๋งํ๊ณ ์ธ๋ฑ์ฑํ ์ ์์ต๋๋ค.
- ์ ์ง์ ํ์ด๋๋ ์ด์ : ์คํธ๋ฆฌ๋ฐ SSR์ ์ ์ง์ ํ์ด๋๋ ์ด์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ด๋ HTML ์ฒญํฌ๊ฐ ์คํธ๋ฆฌ๋ฐ๋จ์ ๋ฐ๋ผ ํด๋ผ์ด์ธํธ ์ธก React ์ฝ๋๊ฐ ์ ์ง์ ์ผ๋ก ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ฒจ๋ถํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํธ์์ฉ ๊ฐ๋ฅํ๊ฒ ๋ง๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
- ํฅ์๋ ๋ฆฌ์์ค ํ์ฉ: ๋ ๋๋ง ํ๋ก์ธ์ค๋ฅผ ๋ ์์ ์ฒญํฌ๋ก ๋ถํดํจ์ผ๋ก์จ ์คํธ๋ฆฌ๋ฐ SSR์ ์๋ฒ์ ๋ฆฌ์์ค ํ์ฉ์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
React ์คํธ๋ฆฌ๋ฐ SSR ์๋ ๋ฐฉ์
React ์คํธ๋ฆฌ๋ฐ SSR์ ReactDOMServer.renderToPipeableStream() API๋ฅผ ํ์ฉํ์ฌ HTML ์ฒญํฌ๋ฅผ ํด๋ผ์ด์ธํธ์ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค. ์ด API๋ ์๋ฒ์ ์๋ต ๊ฐ์ฒด์ ํ์ดํ๋ ์ ์๋ ์ฝ๊ธฐ ๊ฐ๋ฅํ ์คํธ๋ฆผ์ ๋ฐํํฉ๋๋ค. ๋ค์์ ์๋ ๋ฐฉ์์ ๋ํ ๊ฐ๋ตํ ์ค๋ช
์
๋๋ค:
- ์๋ฒ๊ฐ ํ์ด์ง ์์ฒญ์ ๋ฐ์ต๋๋ค.
- ์๋ฒ๋
ReactDOMServer.renderToPipeableStream()์ ํธ์ถํ์ฌ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํธ๋ฆผ์ผ๋ก ๋ ๋๋งํฉ๋๋ค. - React ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋จ์ ๋ฐ๋ผ ์คํธ๋ฆผ์ HTML ์ฒญํฌ๋ฅผ ๋ฐฉ์ถํ๊ธฐ ์์ํฉ๋๋ค.
- ์๋ฒ๋ ์คํธ๋ฆผ์ ์๋ต ๊ฐ์ฒด์ ํ์ดํํ์ฌ HTML ์ฒญํฌ๋ฅผ ํด๋ผ์ด์ธํธ์ ์ ์กํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ๋ HTML ์ฒญํฌ๋ฅผ ์์ ํ๊ณ ์ ์ง์ ์ผ๋ก ํ์ํ๊ธฐ ์์ํฉ๋๋ค.
- ๋ชจ๋ HTML ์ฒญํฌ๊ฐ ์์ ๋๋ฉด ๋ธ๋ผ์ฐ์ ๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ด๋๋ ์ดํธํ์ฌ ์ํธ์์ฉ ๊ฐ๋ฅํ๊ฒ ๋ง๋ญ๋๋ค.
React ์คํธ๋ฆฌ๋ฐ SSR ๊ตฌํํ๊ธฐ
React ์คํธ๋ฆฌ๋ฐ SSR์ ๊ตฌํํ๋ ค๋ฉด Node.js ์๋ฒ์ React ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ์ํฉ๋๋ค. ๋ค์์ ๋จ๊ณ๋ณ ๊ฐ์ด๋์ ๋๋ค:
- Node.js ์๋ฒ ์ค์ : Express ๋๋ Koa์ ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ Node.js ์๋ฒ๋ฅผ ์์ฑํฉ๋๋ค.
- React ๋ฐ ReactDOMServer ์ค์น:
react๋ฐreact-domํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค. - React ์ ํ๋ฆฌ์ผ์ด์ ์์ฑ: ์๋ฒ์์ ๋ ๋๋งํ๋ ค๋ ์ปดํฌ๋ํธ๋ก React ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํฉ๋๋ค.
ReactDOMServer.renderToPipeableStream()์ฌ์ฉ: ์๋ฒ ์ฝ๋์์ReactDOMServer.renderToPipeableStream()API๋ฅผ ์ฌ์ฉํ์ฌ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํธ๋ฆผ์ผ๋ก ๋ ๋๋งํฉ๋๋ค.- ์คํธ๋ฆผ์ ์๋ต ๊ฐ์ฒด์ ํ์ดํ: ์คํธ๋ฆผ์ ์๋ฒ์ ์๋ต ๊ฐ์ฒด์ ํ์ดํํ์ฌ HTML ์ฒญํฌ๋ฅผ ํด๋ผ์ด์ธํธ์ ์ ์กํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: ๋ ๋๋ง ๊ณผ์ ์์ ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ํด ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์์์น ๋ชปํ ๋์์ ๋ฐฉ์งํ๊ธฐ ์ํด ์๋ฒ ๋ฐ ํด๋ผ์ด์ธํธ ์ธก์์ ์ค๋ฅ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌํฉ๋๋ค.
- ํ์ด๋๋ ์ด์ ์ ์ํ ์คํฌ๋ฆฝํธ ํ๊ทธ ์ถ๊ฐ: ํด๋ผ์ด์ธํธ ์ธก์์ React ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ด๋๋ ์ดํธํ๊ธฐ ์ํด HTML์ ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ํฌํจํฉ๋๋ค.
์์ ์ฝ๋ ์ค๋ํซ (์๋ฒ ์ธก):
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const App = require('./App'); // Your React component
const app = express();
const port = 3000;
app.get('/', (req, res) => {
const { pipe, abort } = ReactDOMServer.renderToPipeableStream( , {
bootstrapModules: [require.resolve('./client')], // Client-side entry point
onShellReady() {
res.setHeader('content-type', 'text/html; charset=utf-8');
pipe(res);
},
onError(err) {
console.error(err);
res.statusCode = 500;
res.send('Sorry, something went wrong
');
}
});
setTimeout(abort, 10000); // Optional: Timeout to prevent indefinite hanging
});
app.use(express.static('public')); // Serve static assets
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
์์ ์ฝ๋ ์ค๋ํซ (ํด๋ผ์ด์ธํธ ์ธก - `client.js`):
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.hydrateRoot(document,
);
์์ React ์ฑ ์ปดํฌ๋ํธ (App.js):
import React, { Suspense } from 'react';
function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Data loaded successfully!");
}, 2000);
});
}
function SlowComponent() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetchData().then(result => setData(result));
}, []);
if (!data) {
throw new Promise(resolve => setTimeout(resolve, 2000)); // Simulate a loading delay
}
return {data}
;
}
export default function App() {
return (
Welcome to Streaming SSR!
This is a demonstration of React Streaming SSR.
Loading... }>
์ด ์์๋ ๋๋ฆฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์๋ฎฌ๋ ์ด์
ํ๋ ๊ฐ๋จํ ์ปดํฌ๋ํธ(`SlowComponent`)๋ฅผ ๋ณด์ฌ์ค๋๋ค. Suspense ์ปดํฌ๋ํธ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋์ฒด UI(์: ๋ก๋ฉ ํ์๊ธฐ)๋ฅผ ํ์ํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ ์ ์ง์ ๋ ๋๋ง ๋ฐ ์ฌ์ฉ์ ๊ฒฝํ ํฅ์์ ๋งค์ฐ ์ค์ํฉ๋๋ค. `renderToPipeableStream`์ `bootstrapModules` ์ต์
์ React์๊ฒ ํ์ด๋๋ ์ด์
์ ์ํด ๋ก๋ํ ํด๋ผ์ด์ธํธ ์ธก ์คํฌ๋ฆฝํธ๋ฅผ ์๋ ค์ค๋๋ค.
์ ์ง์ ๋ ๋๋ง์ ์ํ Suspense ์ฌ์ฉ
Suspense๋ ์ ์ง์ ๋ ๋๋ง์ ๊ฐ๋ฅํ๊ฒ ํ๋ React์ ํต์ฌ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๋ ๋ ๋๋ง์ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์๋ ์ปดํฌ๋ํธ(์: ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์)๋ฅผ ๊ฐ์ธ๊ณ , ์ปดํฌ๋ํธ๊ฐ ๋ก๋ฉ๋๋ ๋์ ํ์ํ ๋์ฒด UI๋ฅผ ์ง์ ํ ์ ์๊ฒ ํฉ๋๋ค. ์คํธ๋ฆฌ๋ฐ SSR์ ์ฌ์ฉํ ๋, Suspense๋ ์๋ฒ๊ฐ ๋์ฒด UI๋ฅผ ํด๋ผ์ด์ธํธ์ ๋จผ์ ๋ณด๋ด๊ณ , ์ค์ ์ปดํฌ๋ํธ ์ฝํ ์ธ ๋ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ฉด ์คํธ๋ฆฌ๋ฐํ๋๋ก ํฉ๋๋ค. ์ด๋ ์ฒด๊ฐ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ๋์ฑ ํฅ์์ํต๋๋ค.
Suspense๋ ํ์ด์ง์ ํน์ ๋ถ๋ถ์ด ์ค๋น๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋๋จธ์ง ํ์ด์ง๊ฐ ๋ก๋๋ ์ ์๋๋ก ํ๋ ํ๋ ์ด์คํ๋๋ผ๊ณ ์๊ฐํด๋ณด์ธ์. ๋ง์น ์จ๋ผ์ธ์ผ๋ก ํผ์๋ฅผ ์ฃผ๋ฌธํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ํผ์๊ฐ ์ค๋น๋๋ ๋์ ์น์ฌ์ดํธ๋ฅผ ๋ณด๊ณ ์ํธ์์ฉํ ์ ์์ต๋๋ค. ํผ์๊ฐ ์์ ํ ์กฐ๋ฆฌ๋ ๋๊น์ง ์๋ฌด๊ฒ๋ ๋ณด์ง ์๊ณ ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์์ต๋๋ค.
๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
React ์คํธ๋ฆฌ๋ฐ SSR์ ์๋นํ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ์ผ๋์ ๋์ด์ผ ํ ๋ช ๊ฐ์ง ๊ณ ๋ ค ์ฌํญ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ์์ต๋๋ค:
- ์ค๋ฅ ์ฒ๋ฆฌ: ๋ ๋๋ง ๊ณผ์ ์์ ๋ฐ์ํ ์ ์๋ ๋ชจ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ํด ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์์์น ๋ชปํ ๋์์ ๋ฐฉ์งํ๊ธฐ ์ํด ์๋ฒ ๋ฐ ํด๋ผ์ด์ธํธ ์ธก์์ ์ค๋ฅ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ฆฌ์์ค ๊ด๋ฆฌ: SSR๊ณผ ๊ด๋ จ๋ ์ฆ๊ฐ๋ ๋ถํ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋ฒ ๋ฆฌ์์ค๋ฅผ ์ต์ ํํฉ๋๋ค. ์บ์ฑ ๋ฐ ๊ธฐํ ์ฑ๋ฅ ์ต์ ํ ๊ธฐ์ ์ฌ์ฉ์ ๊ณ ๋ คํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ ์ธก ํ์ด๋๋ ์ด์ : HTML ์ฒญํฌ๊ฐ ์คํธ๋ฆฌ๋ฐ๋ ํ ํด๋ผ์ด์ธํธ ์ธก ์ฝ๋๊ฐ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ด๋๋ ์ดํธํ๋์ง ํ์ธํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํธ์์ฉ ๊ฐ๋ฅํ๊ฒ ๋ง๋๋ ๋ฐ ํ์์ ์ ๋๋ค. ํ์ด๋๋ ์ด์ ์ค์ ์ํ ๊ด๋ฆฌ ๋ฐ ์ด๋ฒคํธ ๋ฐ์ธ๋ฉ์ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ด์ญ์์ค.
- ํ ์คํ : ์คํธ๋ฆฌ๋ฐ SSR ๊ตฌํ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๊ณ ์์๋๋ ์ฑ๋ฅ ์ด์ ์ ์ ๊ณตํ๋์ง ์ฒ ์ ํ ํ ์คํธํฉ๋๋ค. TTFB ๋ฐ ๊ธฐํ ์งํ๋ฅผ ์ถ์ ํ๊ธฐ ์ํด ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ๋ณต์ก์ฑ: ์คํธ๋ฆฌ๋ฐ SSR์ ๊ตฌํํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณต์ก์ฑ์ด ์ถ๊ฐ๋ฉ๋๋ค. ๊ตฌํํ๊ธฐ ์ ์ ์ฑ๋ฅ ์ด์ ๊ณผ ์ถ๊ฐ๋ ๋ณต์ก์ฑ ์ฌ์ด์ ๊ท ํ์ ํ๊ฐํ์ญ์์ค. ๋ ๊ฐ๋จํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ์ด์ ์ด ๋ณต์ก์ฑ์ ์์ํ์ง ๋ชปํ ์๋ ์์ต๋๋ค.
- SEO ๊ณ ๋ ค ์ฌํญ: SSR์ด ์ผ๋ฐ์ ์ผ๋ก SEO๋ฅผ ๊ฐ์ ํ์ง๋ง, ๊ฒ์ ์์ง ํฌ๋กค๋ฌ์ ๋ง๊ฒ ๊ตฌํ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ๋์๋์ง ํ์ธํ์ญ์์ค. ๊ฒ์ ์์ง์ด ์ฝํ ์ธ ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ก์ธ์คํ๊ณ ์ธ๋ฑ์ฑํ ์ ์๋์ง ํ์ธํฉ๋๋ค.
์ค์ ์ฌ๋ก ๋ฐ ์ฌ์ฉ ์ฌ๋ก
React ์คํธ๋ฆฌ๋ฐ SSR์ ๋ค์๊ณผ ๊ฐ์ ์น์ฌ์ดํธ์ ํนํ ์ ์ฉํฉ๋๋ค:
- ์ฝํ ์ธ ์ค์ฌ ํ์ด์ง: ๋ง์ ํ ์คํธ, ์ด๋ฏธ์ง ๋๋ ๋น๋์ค๊ฐ ์๋ ์น์ฌ์ดํธ๋ ์ฝํ ์ธ ๊ฐ ์ ์ง์ ์ผ๋ก ํ์๋๋๋ก ํ์ฉํ๋ฏ๋ก ์คํธ๋ฆฌ๋ฐ SSR์ ์ด์ ์ ์ป์ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ์ค์ฌ ์ ํ๋ฆฌ์ผ์ด์ : API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ ธ์์ง๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ธฐ ์ํด Suspense๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ ์์๊ฑฐ๋ ์น์ฌ์ดํธ: ์คํธ๋ฆฌ๋ฐ SSR์ ์ ํ ํ์ด์ง๋ฅผ ๋ ๋น ๋ฅด๊ฒ ๋ก๋ํ์ฌ ์ผํ ๊ฒฝํ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๋ ๋น ๋ฅด๊ฒ ๋ก๋๋๋ ์ ํ ํ์ด์ง๋ ๋ ๋์ ์ ํ์จ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- ๋ด์ค ๋ฐ ๋ฏธ๋์ด ์น์ฌ์ดํธ: ์คํธ๋ฆฌ๋ฐ SSR์ ํผํฌ ํธ๋ํฝ ์๊ฐ์๋ ๋ด์ค ๊ธฐ์ฌ ๋ฐ ๊ธฐํ ์ฝํ ์ธ ๊ฐ ๋น ๋ฅด๊ฒ ํ์๋๋๋ก ๋ณด์ฅํ ์ ์์ต๋๋ค.
- ์์ ๋ฏธ๋์ด ํ๋ซํผ: ์คํธ๋ฆฌ๋ฐ SSR์ ํผ๋ ๋ฐ ํ๋กํ์ ๋ ๋น ๋ฅด๊ฒ ๋ก๋ํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์์: ๊ธ๋ก๋ฒ ์ ์์๊ฑฐ๋ ์น์ฌ์ดํธ
์ ์ธ๊ณ ๊ณ ๊ฐ์๊ฒ ์ ํ์ ํ๋งคํ๋ ๊ธ๋ก๋ฒ ์ ์์๊ฑฐ๋ ์น์ฌ์ดํธ๋ฅผ ์์ํด๋ณด์ธ์. ์คํธ๋ฆฌ๋ฐ SSR์ ์ฌ์ฉํ๋ฉด ์น์ฌ์ดํธ๋ ์ฌ์ฉ์์ ์์น์ ๊ด๊ณ์์ด ๋ ๋น ๋ฅด๊ณ ๋ฐ์์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ณธ์ ์๋ ์ฌ์ฉ์๊ฐ ์ ํ ํ์ด์ง๋ฅผ ํ์ํ ๋ ์ด๊ธฐ HTML ์ฒญํฌ๋ฅผ ๋น ๋ฅด๊ฒ ์์ ํ์ฌ ์ ํ ์ด๋ฏธ์ง์ ๊ธฐ๋ณธ ์ ๋ณด๋ฅผ ๊ฑฐ์ ์ฆ์ ๋ณผ ์ ์์ต๋๋ค. ์น์ฌ์ดํธ๋ ๊ทธ๋ฐ ๋ค์ ์ ํ ์ค๋ช ๋ฐ ๋ฆฌ๋ทฐ์ ๊ฐ์ ๋๋จธ์ง ์ฝํ ์ธ ๋ฅผ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ ๋๋ก ์คํธ๋ฆฌ๋ฐํ ์ ์์ต๋๋ค.
๋ํ ์น์ฌ์ดํธ๋ ๋ค์ํ API์์ ์ ํ ์ธ๋ถ ์ ๋ณด๋ ๋ฆฌ๋ทฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋์ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ํ์ํ๊ธฐ ์ํด Suspense๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ๊ฐ ๋ก๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋์ ํญ์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ณผ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
React ์คํธ๋ฆฌ๋ฐ SSR์ ๋์
React ์คํธ๋ฆฌ๋ฐ SSR์ ๊ฐ๋ ฅํ ๊ธฐ์ ์ด์ง๋ง, ๊ณ ๋ คํ ๋ค๋ฅธ ๋์๋ ์์ต๋๋ค:
- ์บ์ฑ์ ์ฌ์ฉํ ๊ธฐ์กด SSR: ๋ ๋๋ง๋ HTML์ ์๋ฒ์ ์ ์ฅํ๊ณ ํด๋ผ์ด์ธํธ์ ์ง์ ์ ๊ณตํ๋ ์บ์ฑ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํฉ๋๋ค. ์ด๋ ์์ฃผ ์ก์ธ์คํ๋ ํ์ด์ง์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
- ์ ์ ์ฌ์ดํธ ์์ฑ(SSG): ๋น๋ ์๊ฐ์ HTML์ ์์ฑํ๊ณ ํด๋ผ์ด์ธํธ์ ์ง์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์์ฃผ ๋ณ๊ฒฝ๋์ง ์๋ ์ฝํ ์ธ ๊ฐ ์๋ ์น์ฌ์ดํธ์ ์ ํฉํฉ๋๋ค. Next.js ๋ฐ Gatsby์ ๊ฐ์ ํ๋ ์์ํฌ๋ SSG์ ํ์ํฉ๋๋ค.
- ์ฌ์ ๋ ๋๋ง: ํค๋๋ฆฌ์ค ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ ์๊ฐ ๋๋ ๋ฐฐํฌ ์๊ฐ์ HTML์ ๋ ๋๋งํ๊ณ ํด๋ผ์ด์ธํธ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ SSR๊ณผ SSG์ ์ด์ ์ ๊ฒฐํฉํ ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
- ์ฃ์ง ์ปดํจํ : ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ์์๊ฒ ๋ ๊ฐ๊น์ด ์ฃ์ง ์์น์ ๋ฐฐํฌํฉ๋๋ค. ์ด๋ ์ง์ฐ ์๊ฐ์ ์ค์ด๊ณ TTFB๋ฅผ ๊ฐ์ ํฉ๋๋ค. Cloudflare Workers ๋ฐ AWS Lambda@Edge์ ๊ฐ์ ์๋น์ค๋ ์ฃ์ง ์ปดํจํ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
๊ฒฐ๋ก
React ์คํธ๋ฆฌ๋ฐ SSR์ ์น์ฌ์ดํธ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ๋ฐ ์ ์ฉํ ๊ธฐ์ ์ ๋๋ค. ๋ ๋๋ง ํ๋ก์ธ์ค๋ฅผ ๋ ์์ ์ฒญํฌ๋ก ๋ถํดํ์ฌ ํด๋ผ์ด์ธํธ์ ์คํธ๋ฆฌ๋ฐํจ์ผ๋ก์จ ์คํธ๋ฆฌ๋ฐ SSR์ ์ด๊ธฐ ๋ก๋ฉ ์๊ฐ์ ๋จ์ถํ๊ณ , ์ํธ์์ฉ์ฑ์ ํฅ์์ํค๋ฉฐ, SEO๋ฅผ ๊ฐ์ ํฉ๋๋ค. ์คํธ๋ฆฌ๋ฐ SSR ๊ตฌํ์ ์ ์คํ ๊ณํ๊ณผ ์คํ์ ์๊ตฌํ์ง๋ง, ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ์ฐธ์ฌ๋ฅผ ์ฐ์ ์ํ๋ ์น์ฌ์ดํธ์๋ ์๋นํ ์ด์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์น ๊ฐ๋ฐ์ด ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์คํธ๋ฆฌ๋ฐ SSR์ ์ธ๊ณํ๋ ์ธ์์์ ๋น ๋ฅด๊ณ ๋ฐ์์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ์ ์ ๋ ์ค์ํ ๊ธฐ์ ์ด ๋ ๊ฒ์ ๋๋ค. ์ด ๊ธ์ ์ค๋ช ๋ ๊ฐ๋ ์ ์ดํดํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ตฌํํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ค์ React ์คํธ๋ฆฌ๋ฐ SSR์ ํ์ฉํ์ฌ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์ฑ๋ฅ์ด ๋ฐ์ด๋๊ณ ๋งค๋ ฅ์ ์ธ ์น์ฌ์ดํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.