SPA 라우팅 vs 전통적 페이지 이동 (브라우저의 히스토리 관리 메커니즘)

권도훈·2024년 12월 16일

문제

프로젝트 진행 중에 페이지 이동을 위해 라우팅 방식을 선택할 필요가 있었다. useNavigate 훅을 사용하는 방법과 window.location.href 값을 변경하는 방법 2가지를 알고 있었고, 2개의 차이에 대해서 모르고 있었기때문에 조금 더 편한 방식인 window.location.href 값을 수정하는 방법을 채택했다.

그러나 이러한 방식으로 페이지를 이동할 때는 전역 상태 라이브러리에 담아둔 값들이 초기화되는 문제가 발생했다.

왜 이런 문제가 발생하는지 알아보았고, history 개념과 관련있다는 것을 알게되었다.

학습

History(히스토리)란 무엇일까?
우리가 웹사이트를 돌아다니면서 뒤로가기나 앞으로가기 버튼을 누르는 경험을 떠올려보자. 지금 보고 있는 웹페이지 이전에 어떤 페이지를 봤는지, 그 전에는 또 어떤 페이지를 봤는지가 모두 순서대로 기록되어 있어, 필요할 때 쉽게 이전 페이지로 돌아갈 수 있는 것이다. 이처럼 사용자가 방문한 웹페이지들의 이동 경로를 쌓아둔 목록이 바로 히스토리(History)라고 할 수 있다.
실제로, 브라우저 콘솔창에서 history를 찍어보면 아래와 같이 보여준다.

useNavigate는 React Router와 같은 SPA(Single Page Application) 라우팅 라이브러리에서 제공하는 훅으로, 내부적으로 히스토리 객체를 통해 이동을 처리한다. 이 때, useNavigate는 브라우저 히스토리에 새로운 엔트리를 추가하거나(push), 현재 히스토리 항목을 대체(replace)하는 방식으로 작동하므로, SPA의 라우팅 이력(?)을 직접 관리하고 조작할 수 있다. 결과적으로 SPA 내의 페이지 전환은 히스토리 스택에 기록되어, 뒤로가기 버튼 등을 통한 사용자 이동이 원활하게 지원된다.

반면에, location.href 값 변경 방식은 브라우저가 원시적으로 제공하는 페이지 이동 방식으로, 새로운 URL을 설정하면 브라우저는 서버로부터 문서를 다시 로드하고 전체 페이지를 새로 고침한다. 이 때 새로운 요청이 발생하며, 브라우저 수준에서 히스토리 스택에 새로운 항목이 추가된다.
이러한 동작 방식은 예전부터 쓰이던 전통적인 웹 방식(멀티페이지 애플리케이션, MPA)이다.
예를 들어, 예전에 링크를 클릭하면 서버에 요청을 보내고, 새로운 HTML 페이지를 받아와 화면을 갱신하였는데, 이때마다 브라우저 이력에 새로운 페이지가 쌓였다.

분석 및 결론

1. 왜 useNavigate를 사용하여 페이지 이동했을 때는, 전역 상태 값이 초기화 되지 않는가?

위에서 학습했듯이 SPA 방식으로 라우팅을 처리할 경우, 브라우저가 실제로 페이지를 새로 불러오는(새로고침) 일이 발생하지 않는다. 대신 자바스크립트 라우팅 라이브러리가 history API를 활용해 URL만 변경하거나 히스토리를 조작함으로써 “마치 페이지가 이동한 것처럼” 보이게 하는 것이다.

전통적인 방식(location.href과 같은)으로 페이지가 이동하면, 브라우저는 새로운 HTML 문서를 받아와 렌더링하고 메모리에 있던 모든 상태를 초기화한다. 그러나 SPA에서는 URL 변경 시에도 브라우저는 기존에 로드된 하나의 HTML 문서 안에서만 동작하고, 필요한 부분만 자바스크립트로 교체합니다.

따라서 웹 애플리케이션 내에서 관리하는 전역 상태는 메모리에 남아 있고, 초기화되지 않는다.

2. 그러면 무조건 SPA 라우팅 방식이 성능이 더 좋은가?

전통적 MPA으로 페이지 전환 시, 각 페이지는 서버에서 새로운 HTML, CSS, JS 등을 다시 받아오게 된다. 초기 로딩 시간이 들지만, 각 페이지가 상대적으로 독립적이므로 특정 페이지가 간단하다면 초기 렌더링이 SPA보다 가볍게 느껴질 수 있다.
왜냐하면, 작은 규모의 사이트나 자바스크립트 의존도가 낮은 웹페이지라면 오히려 전체 번들이 큰 SPA를 구축하는 것보다 빠르게 페이지를 로딩하는 경우도 있기때문이다.

따라서, 단순한 페이지 전환만 필요한 아주 간단한 사이트라면, 굳이 SPA 환경을 구축하지 않고 location.href로 페이지 전환을 하는 것이 초기 구현이 간단하고, 특정 상황에서는 초기 로딩량이 적어 실제로 초기 접근 성능 측면에서 유리할 수도 있다.

그러나 사용자 경험 측면에서 페이지 전환 시마다 전체 화면 갱신과 서버 요청이 필요하므로, 반복적인 전환 상황에서는 SPA 방식보다 느리게 느껴질 수 있다.
따라서 성능을 어떤 기준으로 보느냐(초기 로딩 속도, 전환 속도, 확장성)에 따라 답변이 달라지며, 단순한 페이지 전환 위주라고 해서 무조건 location.href가 성능이 더 좋다고는 하기 어렵다.

SSR(서버사이드 렌더링)과 CSR(클라이언트사이드 렌더링) 관점에서 살펴보기

지금까지는 SPA(useNavigate)와 전통적 MPA(location.href) 방식의 차이를 중심으로 살펴보았지만, 웹 애플리케이션 렌더링 전략을 이해하려면 SSR과 CSR개념을 함께 고려하는 것이 좋다.

CSR(클라이언트사이드 렌더링)
일반적인 SPA 방식으로, 최초 로딩 시 HTML은 최소한으로 받고 대부분의 UI를 자바스크립트로 동적으로 렌더링한다. 이후 페이지 전환은 useNavigate 등 클라이언트 라우팅을 활용하여, 전체 페이지가 아닌 필요한 부분만 교체하므로 전역 상태가 유지되고 전환 속도가 빠르다. 다만 초기 로딩 시 자바스크립트 번들 크기에 따라 성능에 영향이 있을 수 있다.

SSR(서버사이드 렌더링)
첫 페이지를 서버에서 미리 렌더링하여 완성된 HTML을 전달하므로, 초기 로딩 속도가 빠르고 SEO에 유리하다. 이후 하이드레이션 과정을 거쳐 SPA처럼 동작하는 하이브리드 방식을 취할 수 있어, 초기 접근성과 반복 전환 시 경험 모두를 일정 수준 만족시킬 수 있다. 즉, SSR을 도입하면 SPA가 가진 초기 로딩 부담을 줄이고, MPA의 빈번한 전체 페이지 로딩 문제를 완화할 수 있다.

하이드레이션(hydration)란 무엇일까?
우리가 SSR을 통해 웹페이지를 처음 열 때, 브라우저는 이미 서버에서 만들어진 완성된 HTML을 받아 화면에 바로 보여준다. 이 덕분에 사용자는 페이지를 빨리 볼 수 있지만, 아직 이 HTML은 “정적인 상태”일 뿐, 브라우저 안에서 동적으로 동작하는 자바스크립트 로직(이벤트 처리, 상태 업데이트 등)은 연결되지 않은 상태다.
하이드레이션 과정은 이 “정적인 HTML”을 “상호작용 가능한 페이지”로 만드는 단계라고 할 수 있다.

정리하자면, 라우팅 방식비교에 SSR/CSR 관점을 더하면, 단순히 MPA와 SPA의 대립 구도를 넘어 프로젝트 상황에 맞춰 렌더링 전략을 최적화할 수 있는 판단 근거를 얻을 수 있다. SEO나 초기 접근 속도가 중요한 경우 SSR 도입을, 많은 상태 유지와 빈번한 화면 전환이 필요한 경우 CSR 기반 SPA 전략을 선택하거나, 두 방식을 혼합하는 등 상황에 따라 유연하게 대처할 수 있다.

profile
🏃🏻

0개의 댓글