과거 리액트 애플리케이션을 만들때는 CRA(create-react-app)이 각광받았지만 요즘은 서버사이드 렌더링을 지원하는 Next.js와 같은 프레임워크가 큰 인기를 끌고 있다.
싱글 페이지 애플리케이션
SPA(Single Page Application) 이란 렌더링과 라우팅에 필요한 대부분의 기능을 서버가 아닌 JS에 의존하는 방식을 의미한다.
최처에 첫 페이지에서 데이터를 모두 불러온 후 페이지 전환을 위한 모든 작업을 JS와 브라우저의 history.pushState와 history.replaceState로 이뤄진다.
이러한 작동방식은 최초 로딩해야할 JS리소스가 커진다는 단점이 존재하긴 하지만 로딩 이후 서버를 거쳐 필요한 리소스를 받아올 일이 적어져 사용자에게 훌륭한 UI/UX를 제공한다는 장점이 있다.
전통적인 방식의 애플리케이션
과거 서버 사이드에서 작동하던 전통적인 방식은 페이지 전환이 발생할 때마다 새롭게 페이지를 요청하고 HTML 페이지를 다운로드해 파싱하는 작업을 거친다.
이런 방식을 이용하면 어쩔수 없이 페이지 전환 시 부자연스러운 모습이 생기게 된다.
이런 방식을 모두 JS로한다면 페이지 전환 시에 리소를 다운로드받는 방식을 스킵하기때문에 자연스러운 페이지 전환이 가능하다.
현재 SPA중에서 완성도가 높다고 손꼽히는 대표적 페이지는 Gmail이다.
위와같이 gmail loading 화면으로 모든 리소스를 가져온 후에는 매끄럽게 전환이 된다.
이러한 장점때문에 많은 웹페이지들이 SPA방식을 채택했다.
과거 PHP나 JSP를 기반으로 대부분이 웹 애플리케이션을 만들때는 서버사이드가 많이 이뤄졌다. 하지만 JS가 점점 다양한 작업을 수행하게 되면서 JS를 모듈화하자는 방안이 나왔고 이에 등장한것이 CommonJS와 AMD(Asynchronous Module Definition)이다. 이런 JS모듈화 , 사용자 기기의 성능 향상 , 인터넷 속도 발전 등과 함께 JS에서 할 수 있는 일이 점차 다양해졌다.
이러한 과정에서 나온 React,Vue,Augular의 시대가 왔고 따라서 오늘날 웹 애플리케이션은 JS를 제외하고는 페이지를 보여주는게 불가능할 정도로 JS에 의존하게 되었다.
JAM 스택 (JavaScript , API , Markup) 스택
Linux,Apache,MySQL,PHP/Python 등 LAMP스택으로 구성되어있었던 기존의 웹 개발 구조는 대부분의 처리를 서버에서 했어야 했는데 앞서말한 React와 같은 프레임워크의 등장으로 JAM 스택 개발구조가 가능해졌다. 이에 따라 MEAN(MongoDB,Express.js,AngularJS,Node.js) , MERN(MongoDB,Express.js,React,Node.js) 등 API 서버까지 JS로 구현하는 구조까지 나왔다.
아래 JS파일의 크기를 보자.
이러한 SPA의 유행과 더불어서 2000년대 에 비해서 JS의 코드크기가 10배정도 불어난 것을 확인할 수 있다. 그렇다면 웹페이지 속도는 얼마나 개선되었을까?
기술 발전이 획기적으로 일어났음에도 생각보다 로딩속도의 발전이 이뤄지지 못한 점을 볼 수 있다. 특히 모바일에서 웹페이지에 접속하는 경우 이 시간은 눈에 띌정도로 보인다.
위 그래프를 보면 평균적으로 모바일 페이지에서 대기해야하는 시간이 10초이상이 걸리는 것을 볼 수 있다. 즉 사용자기기,인터넷 등 속도가 빨라졌음에도 사용자가 느끼는 속도는 2011년이나 지금이나 별 차이가 없다.
서버사이드 렌더링
싱글페이지 애플리케이션이 JS를 활용하여 한 페이지에서만 렌더링을 수행하는것과 반대로 서버 사이드 렌더링은 최초에 사용자에게 보여줄 페이지를 서버에서 빠르게 렌더링한다.
서버 사이드 방식을 채택하면 렌더링에 필요한 작업을 모두 서버에서 수행하기 때문에 비교적 안정적인 렌더링이 가능하다.
서버 사이드 렌더링의 장점
1. 최초 페이지 진입이 빠르다
First Contentful Patin(최초 페이지에 접근해서 유의미한 정보가 그려지는 시간) 이 빠르다. SPA 라면 사용자가 페이지에 진입하고 JS 리소스 파일들을 다운로드 하고 API요청 등의 작업이 이뤄진 이후에 화면에 렌더링이 이뤄진다.
서버사이드 렌더링을 활용하면 이 작업이 더 빠르다. 서버에서 HTTP요청을 하는것이 더 빠르고 HTML또한 서버에서 미리 그려서 주는것이 클라이언트에서 기존 HTML에 삽입하는것보다 빠르다. 다만 서버가 사용자에게 렌더링을 제공할 수 있을 정도의 충분한 리소스가 있는 경우에 유리하단 점을 알아두자.
2. 검색엔진 & SNS 공유 등 메타데이터 제공이 쉽다.
서버사이드 렌더링은 검색 엔진 최적화에 유용하다.
검색 엔진이 사이트에서 정보를 가져가는 순서는 아래와 같다.
1. 검색 엔진 로봇이 페이지에 진입
2. 페이지가 HTML 정보를 제공하여 이 HTML을 다운로드 (JS는 실행 X)
3. HTML의 오픈 그래프나 meta태그 정보를 기반으로 페이지의 정보를 가져옴
즉 검색엔진은 페이지 내부의 JS파일을 실행하지 않는다. 따라서 JS코드의 실행이 렌더링과 직접적으로 연관되는 싱글페이지 애플리케이션은 검색엔진에서 불리하게 작용된다.
3. 누적 레이아웃 이동이 적다.
사용자에게 페이지를 보여준 후 HTML 정보가 추가되거나 삭제되어 화면이 덜컥거리는 듯한 부정적 사용자 경험이 줄어든다. 블로그글 & 광고가 있는 페이지에서 광고가 뒤늦게 삽입되어 화면이 덜컥거리는 경험을 해본적 있을것이다.
SPA에서 API들의 응답 결과의 시간이 제각각이기에 이런 문제가 발생할 수 있다. 물론 useEffect와 같은 리액트 훅을 사용한다면 서버사이드 애플리케이션에서도 같은 문제가 발생할 순 있따. 단 이는 리액트 18에서 등장한 스트림으로 해결할 수 있다. (이는 후에 다룬다고 한다.. 처음들어봤다)
4. 디바이스 성능에 비교적 자유롭다.
JS리소스실행은 100% 사용자 디바이스 성능에 의존적이다. 서버 사이드 렌더링을 사용하면 이 부담을 서버에 나눌 수 있어 디바이스 성능으로부터 조금 더 자유로워 질 수 있다.
물론 인터넷속도,서버 부담 증가 등등 적절한 처리가 없다면 서버사이드 렌더링을 쓰더라도 느려질 수 있다.
5. 보안에 좀 더 안전
JAM스택을 채택하면 애플리케이션의 모든 활동이 브라우저에 노출된다는 것이다. 특히 API호출,인증같은 민감한 작업들도 포함되어 있어 이런 부분을 항상 생각하며 개발해야 한다. 서버사이드 렌더링같은 경우 이런 작업을 브라우저에만 제공하여 이런 보안 위험을 피할 수 있다.
서버사이드 렌더링의 단점
1. 소스코드 작성시 서버를 고려해야 함
브라우저 전역 객체인 window 나 sessionStorage와 같은 전역객체를 서버에서 실행하면 오류가 날 것이다. 특히 이런 window 사용을 위해서는 이를 서버사이드에서 실행되지 않도록 생각해야 한다는 문제가 있다. 결국 이런 경우가 반복되다 보면 최악의 경우 서버 사이드 렌더링의 장점을 잃을 수도 있다.
2. 적절한 서버의 구축
결국 서버사이드 렌더링을 사용했을때 사용자의 부담이 줄어든다는 것은 서버의 부담이 커진다는 것과도 똑같다. 서버사이드 렌더링은 사용자의 요청을 받아 렌더링을 수행할 서버가 필요한데 이 서버 구축이 쉬운것은 아니다.
3. 서비스 지연에 따른 문제
싱글 페이지에서 서비스 지연이 일어난다면 '로딩중'과 같은 적절한 안내를 표시할 수 있지만 서버사이드에서 지연이 일어나면 사용자는 어떤 정보도 받을 수 없다.
애플리케이션의 규모가 커지고 복잡해질때 서버사이드 렌더링은 때때로 더 안좋은 사용자 경험을 제공할 수 있다.
즉 서버사이드 렌더링또한 만능은 아니다!!
잘못된 서버사이드 웹페이지 설계는 성능을 해치며 관리포인트가 서버,클라이언트로 나눠지는 역효과를 가질수도 있으며 어떤 경우에서는 SPA를 쓰는것이 더 효율적일 수도 있다라는 점을 항상 생각하자.
싱글 페이지 애플리케이션 vs 서버 사이드 렌더링 애플리케이션
1. 가장 뛰어난 싱글페이지 애플리케이션은 가장 뛰어난 멀티 페이지 애플리케이션보다 낫다.
Gmail과 같이 완성도 높은 싱글페이지 애플리케이션은 최초 페이지 진입시에 보여줘야할 정보를 잘 요청하고 코드분할등도 잘 지켜져서 사용자 경험이 매우 좋다. 결국 멀티페이지 애플리케이션이 아무리 최적화를 잘해도 브라우저 API와 JS를 활용한 라우팅을 기반으로한 SPA를 이기기는 힘들다.
2. 평균적인 싱글페이지 애플리케이션은 멀티페이지 애플리케이션보다 느리다.
일반적인 SPA는 렌더링,라우팅에 최적화를 신경을 안쓴경우 사용자 기기에 따라 성능이 의존되기에 멀티페이지 애플리케이션보다 아쉬운 경우가 많다. 또한 최근 싱글페이지 애플리케이션에서 발생하는 문제들을 해결하기위한 API또한 브라우저에 추가되고 있다.
페인팅 홀딩(Paint Holding) : 화면을 하얗게 띄우는 대신 이전 페이지의 모습을 잠깐 보여주는 기법
back forward cache : 브라우저 앞으로 가기 , 뒤로가기 실행시 캐시된 페이지를 보여줌
Shared Element Transitions : 페이지 라우팅이 일어났을때 동일요소가 있다면 이를 유지함
현대의 서버 사이드 렌더링
현재 서버사이드 렌더링은 이전의 LAMP방식과는 조금 다르다. 요즘 서버 사이드 렌더링은 싱글페이지 렌더링과 서버사이드 렌더링의 장점을 모두 취한 방식으로 작동한다.
최초 웹페이지에 접근할때는 서버사이드 방식으로 완성된 HTML을 보여주며 그 이후 서버에서 받은 JS를 기반으로 SPA처럼 동작하게 하는 방식을 사용한다. Next.js Remix 등 최근 곽광받는 프레임워크들이 모두 이 방식을 채택한다고 한다.
따라서 싱글페이지 애플리케이션 , 서버사이드 렌더링 애플리케이션 모두 작동원리를 잘 알아야 한다!!
(항상 공부해야 하는 직업이 맞다
'FrontEnd > Deep Dive' 카테고리의 다른 글
[React] Deep Dive 모던 리액트(14) Next.js (0) | 2023.12.29 |
---|---|
[React] Deep Dive 모던 리액트(13) 리액트와 서버사이드 (1) | 2023.12.27 |
[React] Deep Dive 모던 리액트(11) 사용자 정의 훅 & 고차 컴포넌트 (0) | 2023.12.24 |
[React] Deep Dive 모던 리액트(10) useContext,useReducer,기타 훅들 (1) | 2023.12.23 |
[React] Deep Dive 모던 리액트(9) useMemo,useCallback,useRef (0) | 2023.12.22 |