CSR & SSR (클라이언트 사이드 렌더링 & 서버사이드 렌더링) + 왜 CSR은 SEO가 안 좋을까?
'서버 사이드 렌더링'
이라는 말이 자꾸 들렸다. 서버 쪽에서 렌더링을 한다는 의미겠거니 했는데 리액트를 활용한 CSR과 어떤 점에서 다르고, 어떤 점에서 좋은지 비교해서 공부해보고 싶었다.
1. CSR (Client-Side-Rendering)
클라이언트 사이드에서 렌더링 하는 것이다.
리액트의 경우가 CSR를 통해 SPA (Single-Page-Application)를 구현하는 대표적인 예시이다.
바닐라 자바스크립트에서 html파일 안에 태그들을 빼곡히 적어 나갔던 것과 달리,
리액트를 처음 배울 때 index.html - <div id=“root”></div>가 전부였던게 신선했었다.
CSR의 과정을 설명하면 이렇다.
- 클라이언트가 웹사이트에 들어간다 (request)
- 서버에서 html파일을 JS링크와 함께 전달한다(response) 이 때의 html파일은 script, meta, link 등의 태그와 빈 컨텐츠로 구성된 index.html이라고 보면 된다. (위 그림상 2번에 있는 CDN은 가장 가까운 서버에서 콘텐츠를 사용자에게 전송할 수 있게 하는 것)
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
- 브라우저는 html파일을 다운로드 하지만 비어있는 컨텐츠 이기 때문에 화면 또한 빈 화면이다.
링크되어 있는 js파일(root)을 다운로드 한다.
//index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
- js파일에는 어플리케이션에 필요한 로직 뿐만 아니라, 어플리케이션을 구동하는 프레임워크, 라이브러리의 소스 코드들이 모두 들어 있기 때문에 다운로드 받는데 시간이 소요된다.
- 그리고 js파일 해석 중 추가로 data fetch가 필요하다면 그것도 다 해온다.
- 받아온 파일(app.js, JSON파일)들을 기반으로 브라우저는 동적으로 html파일을 생성 (렌더링 !) 해서 사용자에게 최종적인 어플리케이션을 보여주게 된다.
CSR은 이렇듯 모든 것이 완성된 이후에 사용자에게 보여진다.
그래서 첫 화면을 보기 전까지 시간이 오래 걸릴 수 있다는 단점이 있다.
그리고 또 하나의 단점은 상대적으로 좋지 않은 SEO (검색 엔진 최적화)
구글, 네이버와 같은 검색엔진들은 html태그(타이틀, 링크, 설명 등)를 통해 사이트가 어떤 정보를 담고 있는지 분석해서 사용자들이 검색시에 사이트가 표시될 수 있도록 활용하는데(웹 크롤링), CSR의 경우 html태그가 비어 있기 때문에 상대적으로 SEO가 좋지 않다고 할 수 있다.
+ 사실 이 부분이 이해가 가지 않았다. -> 왜 CSR은 SEO에 약할까?
CSR의 경우 View가 Javascript에 의해 구현되고 웹 크롤러 봇들이 Javascript 파일을 실행 못하기 때문에,
비어있는 HTML의 내용을 바탕으로 CSR페이지를 빈 페이지로 인식하게 된다. <body> 안의 태그들이 검색어로서 역할을 못하게 되는 것.
이러한 이유로 당연히 상대적으로 SSR에 비해 SEO에 약하겠지만, body안의 태그들을 읽고 읽지 못하고가 얼마나 큰 차이를 가져오는지가 의문이었다.
리액트에서 사용하는 index.html 안에도 <head>가 있고, meta태그가 있기 때문에 meta 태그를 활용해서 어느 정도 보완이 가능하다고 생각했다.
<meta> title, description을 통해서 SEO를 위한 정보들에 대해서 충분히 기입이 가능하고,
이제는 구글 크롤러가 JS 파일을 지원하고, 네이버에서도 JS 영향도를 기반으로 사이트의 분석을 진행한다고 하니
SSR이 왜 이렇게 핫해야 하는지 이해가 되지 않았다.
그러던 중 리액트 라이브러리 중 SEO단점을 보완할 수 있는 helmet의 사용 예시를 보다가 알게 되었다.
헬멧은 동적으로 SEO에 필요한 메타태그들을 쉽게 변경할 수 있게 도와주는 라이브러리다.
사용법은 아래와 같다.
import React from "react";
import {Helmet} from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example" />
</Helmet>
...
</div>
);
}
};
<Parent>
<Helmet>
<title>My Title</title>
<meta name="description" content="Helmet application" />
</Helmet>
<Child>
<Helmet>
<title>Nested Title</title>
<meta name="description" content="Nested component" />
</Helmet>
</Child>
</Parent>
부모 컴포넌트에서 한번, 자식 컴포넌트에서 한번, 헬멧 라이브러리를 통해 총 두번 메타태그를 사용하고 있는 중이다.
그렇다. 당연한 얘기지만 SEO는 결국 메타 태그의 '양'과도 관련된 문제였다.
SPA에서는 페이지가 하나 즉 html이 하나이다. 그런데 SPA가 아닌 경우라면 여러페이지, 즉 html도 여러 개일 수 있는 것이다.
각 페이지 마다 meta태그를 다르게 지정할 수 있게 되고 더 많은 연관 검색어가 포함될 수 있는 것.
예를 들면,
쇼핑몰 - 1. 신발 - 1) 나이키 , 2) 아디다스
2. 옷 - 1) 자라, 2)유니클로
이렇게 구성되어 있는 쇼핑몰이 있다면,
CSR의 경구 쇼핑몰이라는 하나의 html-meta 태그안에 모든 정보들을 넣기 어렵다.
하지만 각각의 페이지마다 다른 html로 구성되어있고 각각 다른 meta태그 입력이 가능하다면 SEO를 최적화 할 수 있는 것!
여튼 SEO는 중요한 것이기에, 이러한 단점을 해결 하기 위한 SSR이 핫하다.
2. SSR (Server-Side-Rendering)
서버에서 렌더링까지 해서 보내주는 것이다.
- 클라이언트가 웹사이트에 들어간다.
- 서버는 필요한 데이터를 가져와서 HTML파일을 ready to be Rendered 되게 한 뒤에 클라이언트에게 보낸다.
- 덕분에 브라우저는 빠르게 HTML을 렌더링 할 수 있다. 완료되는데로 클라이언트에게 뷰를 보여준다.
- 그리고 JS파일을 다운로드 한다. JS가 다운로드 되기 전이기 때문에 사이트는 보여지기만 할 뿐 interactive하지 않다. (클릭과 같은 것들)
- js파일 준비가 완료되면 interactive 해지게 된다. 브라우저가 제대로 작동한다.
장점으로는 js파일이 받아지기 전에 페이지를 보여주기 때문에 빠르다.
그리고 html에 모든 컨텐츠가 담겨있기 때문에 좋은 SEO를 가진다.
단점으로는 깜빡임 이슈가 있다. SPA처럼 하나의 페이지, 하나의 html안에서 움직이는 것이 아니라,
여러 html, 여러 페이지가 존재하는 것이기 때문에 페이지 이동 시 다시 서버에서 html 페이지를 받아오는 개념이다.
상대적으로 좋지 않은 user interface를 가진다.
두번째로 서버가 과부하에 걸릴 수 있다. 특히 사용자가 많은 사이트일 수록,
'사용자가 클릭을 할 때마다 서버에 요청을 하고 서버는 필요한 데이터를 가져와서 렌더링까지 한 후 response 해준다.'
는 일련의 과정이 필요하기 때문에 과부하 가능성이 있다.
세번째, TTV(Time To View) 와 TTI(Time To Interact)가 다름에서 오는 user interface 문제이다.
렌더링된 페이지가 브라우저에 먼저 도착하고 JS파일은 아직 준비되지 않았을 때,
화면이 보여지고 있음에도 클릭과 같은 상호작용이 안될 수 있기 때문에 유저 입장에서는 당황할 수 있다.
(CSR의 경우 JS까지 다 다운로드가 완료된 이후에 view를 보여주기 때문에 차이가 발생하지 않는다)
SSR:사용자가 웹 페이지에 접속했을 때 서버가 사용자에게 랜더링될 HTML을 응답하여 브라우저가 바로 랜더링할 수 있게한다. 그 후 CSR과 동일하게 자바스크립트 파일을 다운로드 받고 실행한다.
CSR: 사용자가 웹 페이지에 들어왔을 때 브라우저가 자바스크립트 파일을 다운로드 받아 해석한 후 랜더링한다.
참고사이트
https://ajdkfl6445.gitbook.io/study/web/csr-vs-ssr-vs-ssg
https://www.youtube.com/watch?v=iZ9csAfU5Os