티스토리 뷰

1. 웹 페이지 렌더링 방식 CSR, SSR, SSG 각각의 특징과 각 방식을 어떤 상황에 사용하면 좋을지 설명해 주세요.

Client Side Rendering (CSR)

CSR은 클라이언트(브라우저)에서 웹 페이지를 렌더링 하는 것 이다. 동작방식은 다음과 같다.

 

사용자가 사이트에 접속하면 서버에서 index라는 HTML파일을 클라이언트에 보내준다.

이때 받는 index 파일은 body 안에는 id="root"만, 그리고 어플리케이션에서 필요한 자바스크립트 링크만 들어있는, 가장 추상적이고 심플하게 이루어져 있다.

 

따라서 HTML이 텅텅 비어져 있기 때문에 처음 접속 시 빈 화면만 보인다.

이후 링크된 JS파일을 서버로부터 받아오는데 이 JS파일에는 어플리케이션에 필요한 로직들 뿐만 아니라 어플리케이션을 구동하는 프레임워크와 라이브러리의 소스코드들도 다 포함되어 있다.

그러므로 굉장히 사이즈가 커서 다운로드 받는 데 시간이 꽤 소요된다.

 

이후 추가로 필요한 데이터가 있다면 서버로 요청해서 데이터를 받아온 다음, 이것들을 기반으로 동적으로 HTML을 생성해 드디어 사용자에게 최종적인 어플리케이션을 보여주게 된다.


CSR의 장점


1. CSR을 위해 이미 도느 지원 스크립트가 사전에 로드되었기 때문에 CSR의 로드 시간이 줄어들어, 후속 페이지 로드 시간이 더 빠르다. 
2. 별도의 API를 호출할 필요가 없는 페이지이거나 지연 로딩 모듈이 필요치 않다. 또한 이미 스크립트가 캐싱 된 경우 인터넷 없이도 해당 CSR 웹 어플리케이션을 실행할 수 있다.
3. 서버를 호출할 때 마다 전체 UI를 다시 로드할 필요가 없다.

4. TTV와 TTI가 일치하다.

 

TTV와 TTI

1. TTV(Time To View): 사용자가 웹사이트를 보는데까지 걸리는 시간
2. TTI(Time To Interact): 사용자가 클릭을 하거나 인터렉션이 가능하게 되는데 걸리는 시간

웹사이트 성능 분석시 TTV와 TTI도 중요한 요소로 사용된다.

CSR은 사용자가 웹사이트를 볼 수 있음과 동시에 사용자가 인터렉션이 가능해진다.
그러므로 최종적으로 번들링해서 사용자에게 보내주는 자바스크립트 파일을 어떻게 하면 효율적으로 분할할 수 있을지, 어떻게 하면 사용자가 첫 페이지를 보기위해 필수적으로 필요한 것만 보낼 수 있을지 고민해보아야 한다.

SSR은 사용자가 웹사이트를 볼 수 있는 시기와 인터렉션이 가능한 시기의 공백기간이 꽤 존재한다.
그러므로 이 시간의 단차를 줄이기 위해 어떤 노력을 해야할지, 어떻게 더 매끄러운 UI와 UX를 제공할 수 있을지 고민해보아야 한다.


CSR의 단점

 

1. 초기 페이지 로드 시간이 느리다. 
2. SEO에 친화적이지 않다.
물론 자바스크립트를 실행시킬 수 있는 구글 크롤러와 같은 검색엔진 크롤러가 등장하고 있긴하지만, 아직 많은 검색 엔진 크롤러들이 지원되지 않는다.

 

Server Side Rendering (SSR)

SSR은 CSR의 문제점으로 인해 이전의 Static Sites에서 영감을 받아 도입되게 된다.

 

Static Sites (~1990s mid)

1990년 중반까지는 모두 Static Sites였다. Static Sites는 서버에 이미 잘 만들어진 html 문서들이 있고, 사용자가 사이트에 접속하면 해당하는 HTML문서를 서버로부터 받아와 보여주는 형식이다.

문제점은 페이지내에서 다른 링크 클릭하면 다시 서버에서 해당 페이지의 HTML을 받아와 페이지 전체가 업데이트 되어야 하기 때문에 화면이 깜빡거린다. 즉 사용성이 떨어진다.

 

SSR은 웹사이트에 접속하면 서버에서 미리 필요한 데이터들을 모두 가져와 만든 HTML 파일 보내주어, 사용자가 웹사이트를 볼 수 있게 한다. 이후 서버에 HTML 파일을 동적으로 제어할 수 있는 JS파일을 요청해 받아오게 되면 이때부터 사용자의 클릭과 같은 인터렉션들을 처리할 수 있게 된다.

 

SSR의 장점

 

1. 초기 페이지 로드 시간이 빠르다

2. SEO에 친화적이다.

 

SSR의 단점

 

1. Static Sites에서 발생했던 것과 동일하게 blinking(깜빡임) 이슈가 존재한다.

2. 사용자가 무언가 클릭하게 되면 전체 웹사이트를 다시 서버에서 받아와야 하므로 좋지 않은 User experience를 겪을 수 있다.

3. 클릭 시 매번 서버에 요청 필요한 데이터로 HTML을 만들어야 하므로 사용자가 많으면 서버에 과부하가 걸릴 수 있다.

4. TTV와 TTI가 불일치하다.

 

 


2. 본인이 생각하는 CSS-in-JS의 장점과 단점을 설명해 주세요.

내가 생각하는 CSS-in-JS의 장점은 다음과 같다.

1. 모듈성 때문에 클래스 이름의 충돌이 발생하지 않는다.

2. 클래스 네이밍에 대한 고민을 덜 수 있다.

3. JavaSript 환경을 최대한 활용 할 수 있다  ex.자바스크립트 변수를 style에 사용할 수 있다.

 

내가 생각하는 CSS-in-JS의 단점은 다음과 같다.

1. 러닝커브가 높다.

2. 별도의 라이브러리를 설치해야 하므로 번들 크기가 커진다.

3. 스타일이 길어지는 경우 따로 style.js 파일을 만들어야 해서 번거롭다.

 

+)

 

요새  sass에 대해서도 찾아보고 있는데 마침 Spot이라는 제품을 만드는 팀에서 Emotion(CSS-in-JS  중 하나)을 버리고 Sass Modules(+Utility Class)로 바꾸게 된 이유를 다룬 글을 발견했다. (번역) 우리가 CSS-in-JS와 헤어지는 이유

 

저자는 CSS-in-JS의 장점과 단점 그리고 못난 점(Ugly)을 소개하고 성능 이슈로 Emotion과 헤어졌다고 말하는데, 생각지 못한 단점들이 존재한다는 것을 알게되어 단점 위주로 정리해보려 한다.

 

1. CSS-in-JS는 런타임 오버헤드를 더한다.

 

CSS-in-JS는 런타임에 스타일 직렬화를 하면서 성능에 부정적인 영향을 준다. 다시말해 리액트가 렌더링하는 시점에 매번 스타일을 계산하는 경우 그렇지 않은 경우보다 속도가 느려진다.

 

만약 컴포넌트가 자주 렌더링 되는 경우 반복되는 직렬화는 높은 성능비용을 초래할 수 있다.

따라서 런타임 비용이 없는 Sass를 도입한 것으로 결정했다고 한다.

스타일 직렬화

Emotion이 CSS 문자열 또는 객체 스타일을 가져와 document에 삽입할 수 있는 일반 CSS 문자열로 변환하는 과정을 말한다. Emotion은 또한 직렬화 중에 일반 CSS의 해시를 계산하는데 이 해시는 생성된 클래스 이름에서 확인할 수 있다. (예시: css-15nl2r3)

CSS-in-JS를 작성하고 개발자 도구를 열어서 html 파일을 보면 클래스가 알수없는 영문으로 조합되어있는데 이걸 말하나보다.

 

2. CSS-in-JS는 번들 크기를 늘린다.

 

사이트를 방문하는 각 사용자는 CSS-in-JS 라이브러리용 자바스크립트를 다운로드해야 한다.

Emotion은 압축되었을 때 7.9kB이고 styled-components는 12.7kB이이다. 두 라이브러리 모두 거대하지는 않지만 번들 크기가 늘어난다.(비교를 위해 설명하자면 react + react-dom은 44.5KB이다.)

 

3. CSS-in-JS는 React DevTools를 어지럽힌다. 

 

css 프로퍼티를 사용하는 각 요소에 대해 Emotion은 <EmotionCssPropInternal>  <Insertion> 컴포넌트를 렌더링한다. 많은 요소에서 css 프로퍼티를 사용하는 경우 아래 그림처럼 Emotion의 내부 컴포넌트가 React DevTools를 어지럽힐 수 있다.

 

 

모든 기술은 장단점이 있다. 따라서 기술을 사용하기 전에 프로젝트에 적합한 기술인지 잘 판단해서 결정하는게 좋을 것 같다. 

 

 

 

참고

https://www.youtube.com/watch?v=iZ9csAfU5Os

https://junghan92.medium.com/%EB%B2%88%EC%97%AD-%EC%9A%B0%EB%A6%AC%EA%B0%80-css-in-js%EC%99%80-%ED%97%A4%EC%96%B4%EC%A7%80%EB%8A%94-%EC%9D%B4%EC%9C%A0-a2e726d6ace6