SPA 단점에 대한 단상
모바일 시대로 접어들면서 웹 환경에도 많은 변화가 동반되었다.
그 중 SPA(Single Page Application)도 단단히 한몫을 차지하고 있는데, 항간에 들리는 SPA의 단점들을 나열해 보면 크게 세 가지로 압축되는 듯 하다.
1. 초기 구동 속도
2. 검색엔진 최적화(SEO)
3. 보안
4. IE 8 이하 지원 (추가)
사실 이것들은 SPA의 단점이라기 보다는, SPA 구조이기에 당연히 생길수 밖에 없는 상황으로 이해되어야 한다.
모든 소프트웨어 아키텍처 전략에는 트레이드 오프(Trade-off)가 존재한다. 흔히 '은탄환'은 없다는 말처럼, SPA가 모든 웹 애플리케이션에 가장 적합한 구조는 아니다.
SPA를 직역하면 '단일 페이지 어플리케이션'으로, 기존의 전통적인 새로고침 방식의 웹과는 달리 필요한 정적파일을 한번에(나눠서도 가능하다) 모두 다운로드 받고, 이후 사용자와의 상호작용 가운데 필요한 데이터만 서버로부터 (비동기로) 동적으로 받게하여 트래픽의 총량을 줄이고, 네이티브 앱과 유사한 사용자 경험을 제공할 수 있는 어플리케이션 형태이다.
결국 SPA가 추구하는 핵심적인 가치는 웹의 (사용자 경험을 향상시키는, UX) 사용성이라 할 수 있으며 부가적으로 속도의 향상도 얻게 된다.(물론 속도에 큰 틀에서 보면 사용성에 포함시킬 수 있다.)
특히 모바일 환경에서는 트래픽 최소화와 속도 및 반응성, 사용성 등이 보다 중요한 이슈이므로 SPA 구조는 모바일 퍼스트(Mobile First) 전략에서는 거의 모범사례에 가까운 모델이라 할 수 있다.
최근 App-like, Naively Web을 지향하는 구글의 PWA(Progressive Web App) 역시 모바일 환경에서의 웹의 사용성을 향상시키는 일환으로 대두되고 있다. PWA가 SPA를 직접적으로 포함하는 개념은 아니지만 비동기 통신과 SPA 구조는 PWA와 궁합이 잘 맞는 선택이다. 개인적으로 SPA도 PWA와 같은 선상에서 이해되기를 바라는 마음이다.
위에서 언급한 SPA 단점(?)이란 것들도, 가만히 들여다 보면 SPA가 추구하는 사상에서 파생되는 당연한 특징들에 가까우며, 저런 단점들 때문에 SPA 적용에 대해 큰 의문이 든다면, 그것은 SPA 자체의 문제가 아니라 현재 어플리케이션이 SPA모델과는 어울리지 않을 가능성이 더 높다.
다시 말하지만, SPA가 모든 상황에 있어 최고의 아키텍처 전략이 아니라, SPA가 어울리는 곳에 사용했을 때만이 최적의 효과와 효율을 발휘할 수 있을 것이다.
위에서 언급한 SPA의 문제(문제라고 해 두자)들을 하나씩 살펴보자.
1. 초기 구동속도 문제
평소 우리는 많은 모바일 '네이티브 앱'을 사용한다. 당신의 스마트폰에 깔려 있는 많은 앱들을 생각해보라. 이 앱들을 사용하는 우리의 자세(?)를 돌이켜보자.
먼저 앱스토어에서 수메가(mb)에 달하는 앱을, 몇 초에 걸쳐 다운로드 받는다. 그리고 또다시 몇 초의 시간을 설치하는데 할애한다. 아직 끝이 아니다. 설치한 앱을 처음 띄울때 초기 구동을 위한 각종 설정과 초기화 작업을 기다리며 앱 초기배너 혹은 광고배너를 무심히 바라본다.
드디어 앱이 실행되면 그때부터는 큰 기다림 없이 앱을 사용한다. 물론 이제부터는 빠른 응답과 높은 반응성을 만끽(?)하면서 말이다.
(또한 설치된 앱을 종료하고 다시 실행할 때도 약간의 시간을 감수해야 한다.)
이제 SPA로 돌아와보자. SPA 역시 모바일 네이티브 앱과 같은 효과를 웹에서 제공해 주고자 한다.
즉 앱의 사용성을 추구하고자 SPA에서도 초기에 필요한 대부분의 리소스를 다운로드 받는다. 물론 이것은 초기 구동속도를 조금 손해보고 더 많은 가치(전체적인 앱의 속도/반응성/사용성 등)를 추구하기 위함이다.
우리는 모바일 앱(극단적인 예로 모바일 게임을 떠올려 보자)을 사용하면서 초기 구동속도가 치명적인 단점이라고 생각하지 않는다. 오히려 다운로드와 설치과정 및 앱 초기 구동을 위한 약간의 시간들을 오히려 자연스럽게 받아들인다.
SPA 사상도 이와 유사하기에 초기 구동속도가 치명적인 단점이라고 언급되는 것은 곤란하다고 강조하고 싶다.
SPA의 사상은, 더 이상 웹이 단순한 웹 문서(웹 페이지)가 아닌 하나의 응용프로그램으로 바라보기에 개념의 전환이 필요한 것이다.
물론 그럼에도 불구하고 SPA도 (여전히) 웹 이기에 기존 웹의 경험을 무시할 수 없는 측면도 있을 것이다.
이런 조건 말이다. "SPA가 좋은건 알겠는데... 메인 페이지는 무조건 빨리 떠야 합니다."
SPA에서도 이런 상황에 대한 기술적 대안을 마련할 수 있다.
초기 페이지에서 모든 리소스를 다운받지 않고, 리소스를 청크(Chunk) 단위로 묶어서 해당 리소스에 대한 요청이 있을 때만 다운로드 받도록 하는 방법을 적용하면 초기 구동속도 문제를 많이 완화시킬 수 있다.
많은 자바스크립트 모듈 번들러에서 Lazy Loading 혹은 비동기 모듈로딩이라는 이름으로 이런 시나리오를 지원하며, 우리의 훌륭한 Angular에서도 모듈단위로 구성요소를 묶고 청크단위로 다운로드 받게 할 수 있다.
심지어 SPA에 PWA를 조합하면 보다 뛰어난 사용성을 부가적으로 제공할 수도 있다. 초기 구동에 필요한 필수적 파일을 웹쉘로 구성하고 백그라운드에서 서비스워커를 통해 비동기 리소스 탐방(?)을 실현할 수 있다.
다시 강조하지만, SPA에서 초기 구동속도는 더 이상 결정적인 단점으로 논해져서는 안된다.
오히려 현재 적용하려는 웹 사이트가 SPA 사상과 맞지 않는 것이 아닌가 살펴보기 바란다.
2. 검색엔진 최적화(SEO) 문제
SEO는 서버랜더링 방식이 아닌 자바스크립트 기반 비동기 연동 모델(클라이언트 랜더링 방식)에서는 항상 이슈가 되어 왔던 주제이다. SPA로 가면서 극단적(?) 자바스크립트 기반 웹이 되다 보니 그 문제가 더욱 부각되는 것이다. 구글 크롬 브라우저는 최신 웹 트랜드를 반영해서 자사의 검색엔진에서 클라이언트 래더링 방식도 검색 봇(Bot)이 컨텐츠를 가져갈 수 있도록 개선하고 있지만 기타 다른 브라우저에서는 그 방향성이 불투명하다.
그러나 이 문제 역시 비슷한 맥락에서 말할 수 있다.
다시 말하지만, SPA로 구현된 웹은 더 이상 단순한 정보제공을 위한 웹 문서(페이지)가 아니다.
SPA 결과물을 하나의 응용프로그램으로 본다면 기존 웹 페이지의 정보제공이란 측면의 SEO가 맞지 않을 수도 있다는 것이다.
생각해 보자. 모바일 네이티브 앱을 만들면서 SEO를 걱정하는 이는 드물 것이다.
(다시 극단적인 예로, 모바일 게임을 만들면서 SEO가 안된다고 걱정하는 것을 상상해보라)
SPA를 적용하면서도 개념은 여전히 웹 페이지에 머물러 있다면 둘 중 하나일 것이다.
SPA 사상을 이해하지 못했거나 해당 프로젝트가 SPA와 어울리지 않거나!
(다시한번) 그럼에도 불구하고 SPA도 웹이기에 SEO가 되어야 한다면 역시 대안 기술이 존재한다.
prerender.io 같은 상용 솔루션도 존재하고, Angular나 React같은 SPA 프레임워크에서도 서버 랜더링이라는 이름으로 SEO에 대응하고 있다.
Angular의 경우 Angular Universal 이라는 SEO 대응 기술이 이미 존재한다.
아직까지 Node.js나 ASP.NET 서버 환경에서만 서버 랜더링을 지원하지만 향후 다른 서버플랫폼도 지원을 계속 추가해 나갈 것이며, 중요한 것은 SPA로 구현된 모든 페이지가 SEO가 되어야 하는 것은 아닐 것이다.
따라서 SEO에 노출되어야 하는 전략적인 페이지들을 선별해서 서버랜더링 기술을 적용하면 될 것이다.
3. 보안문제
SPA의 보안문제로 자주 언급되는 것이 사용자 정보가, 기존 서버기반 세션이 아닌 클라이언트 기반 쿠키라는 것이다.
그런데 세션은 쿠키 아닌가? 세선도 클라이언트에는 쿠키형태로 저장되고 모든 요청의 헤더에 그 값이 전달된다. 단지 쿠키와 다른점은 서버측에도 클라이언트 쿠키와 매핑되는 세션정보가 저장되어 있다는 것만 다를 뿐 이다.
보안관점에서 보면 쿠키의 가장 큰 문제는 '도용'이다. 쿠키 정보의 기밀성이나 변조는 쉽게 방어할 수 있지만 누군가의 쿠키를 그대로 복사해서 재사용하는 것은 조금더 높은 방어기술을 요구한다.
그런데 이런 쿠키도용은 서버세션이라는 시나리오에서도 동일하게 적용된다. 물론 서버측에 세션만료시간내에 도용해야 한다는 제약이 존재하지만, 요즘 쿠키는 대부분 브라우저 쿠키로 영구적으로 저장하지 않으니 별반 차이가 없다고 보는 것이 맞다.
따라서 사용자 정보저장이라는 측면에서는 SPA의 쿠키나, 기존 서버랜더링 방식의 세션이나 별반 다를 것이 없다. 그리고 요즘 왠만한데는 쿠키 잘 쓰지도 않는다.
SPA의 보안이라는 측면에서 더욱 심각한 것은 핵심로직이 자바스크립트로 구현된다는 점이다.
기존에는 대부분의 비즈니스 로직이 서버에서 수행되어 최종 결과만을 (HTML 덩어리로) 전달받았을 뿐인데, SPA에서는 필요한 데이터만 전달받고 많은 비즈니스 기능을 클라이언트에서 수행하기 때문에 핵심 로직이 노출될 수 있다는 점이 문제라면 문제일 것이다.
따라서 SPA 보안문제를 언급하려면 이 관점에서 풀어나가야 한다.
이것은 별다른 방법이 없다.
핵심로직은 서버에서 수행하도록 하고 중요한 유효성 검사는 양측 모두에서 수행하도록 해야 한다.
유효성 검사의 양측 모두 구현은, 굳이 SPA가 아니더라도 기존방식에서도 그렇게 해 왔었고 해야 되는 것이었다. SPA라서 더욱 신경써야 할 포인트는 바로 클라이언트에서 수행되는 핵심로직을 최소화시키는 것이다.
자바스크립트 난독화만으로 해결될 문제가 아니기에 설계시 고민해야 하는 부분이다.
실제로 게임 어플리케이션을 만들 때 이런 고민을 한다.
4. IE 8 이하 지원
SPA가 비단 Angular, ReactJS로만 만들 수 있는 것은 아니지만, 진정한 SPA 다운 결과물을 만들기 위해서는 이런 프레임워크의 도움이 절실하다.
그리고 이런 최신의 자바스크립트 프레임워크들은 IE8을 지원대상에서 제외하고 있는 추세이다.
따라서 SPA를 진정 원한다면 IE8 이하를 과감히 버리는 것을 고려해야 한다.
그렇게 하지 못한다면, IE8용 대안을 별도로 마련해야 하는데 대국민 서비스에 규모가 큰 조직이라면 해 볼만 하다. 그러나 서비스 특징과 비용 효율 측면을 따져보고 결정할 일이다.
-----------------------------------------------------------------
하나를 얻으면 하나를 잃게 되는 것이 세상사가 아닌가 한다.
SPA로 얻는 가치가 있다면 SPA로 잃는 가치도 있을 것이다. 그런데 SPA에서 언급되는 저러한 단점들이 과연 단점이라 할 수 있는지 의문이 든다.
심지어 SPA의 특징으로 인해 부각되는 몇 가지 문제상황들은 대안 기술로 해결될 수 있는 부분이 많다.
결론을 내리자.
SPA 자체를 보지 말고, 현재 수행하는 프로젝트의 특성을 먼저 살펴보기 바란다.
지금 개발하려는 애플리케이션이 SPA의 사상과 일치하는지 말이다.
당신의 프로젝트에 SPA를 적용하지 않는다고 해서 SPA가 서운해 하거나 하지는 않을 것이다.