Single Page Application
SPA(Single Page Application)는 최초에 하나의 HTML과 JavaScript 번들을 받아 온 뒤, 이후 화면 전환을 서버 요청 없이 클라이언트 측에서 처리하는 웹 애플리케이션 구조입니다. 브라우저 안에서 라우팅과 렌더링을 모두 담당하므로 페이지 이동 시 전체 새로고침이 발생하지 않고, 필요한 데이터만 API로 가져와 화면을 갱신합니다.
▶아키텍처 다이어그램
점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다
전통적인 웹은 링크를 클릭할 때마다 서버에 새 HTML을 요청하고 페이지 전체를 다시 로드합니다. 사용자가 대시보드에서 탭을 바꾸거나, 목록에서 항목을 선택하거나, 필터를 조정할 때마다 화면이 깜빡이며 처음부터 다시 그려집니다. 재생 중이던 음악이 끊기고, 입력 중이던 폼이 초기화되고, 스크롤 위치가 맨 위로 돌아갑니다. 사용자 입장에서는 간단한 동작에 과도한 대기가 발생하고, 개발자 입장에서는 매 요청마다 서버가 같은 레이아웃과 네비게이션을 반복해서 렌더링해야 합니다. 웹이 단순한 문서 열람을 넘어 복잡한 인터랙션을 처리해야 할수록, 매번 서버를 왕복하는 구조가 사용 경험과 개발 효율 양쪽에서 병목이 됩니다.
웹 초기에는 서버가 HTML을 완성해서 보내주는 방식이 자연스러웠습니다. 페이지 수가 적고 인터랙션이 단순했기 때문입니다. 2000년대 들어 Gmail, Google Maps 같은 서비스가 등장하면서 상황이 바뀌었습니다. 이메일을 읽을 때마다 전체 페이지를 새로 받아오는 건 명백한 낭비였고, 지도를 드래그할 때마다 새로고침이 일어나면 쓸 수가 없었습니다. AJAX(Asynchronous JavaScript and XML)가 보편화되면서 페이지 전체를 다시 받지 않고 일부 데이터만 비동기로 가져올 수 있게 됐습니다. 이 기술적 기반 위에서 '아예 처음부터 페이지를 하나만 로드하고 나머지는 전부 JavaScript로 처리하자'는 발상이 자리 잡았습니다. 브라우저의 JavaScript 엔진이 빨라지고, 프론트엔드 프레임워크가 라우팅과 상태 관리를 체계적으로 지원하면서 SPA는 복잡한 웹 애플리케이션의 기본 구조로 정착했습니다.
SPA에서 사용자가 URL을 처음 입력하면 서버는 거의 비어 있는 HTML 파일과 JavaScript 번들을 보냅니다. 이 HTML에는 콘텐츠가 없고, `<div id="root"></div>` 같은 빈 컨테이너만 있습니다. 브라우저가 JS 번들을 다운로드하고 실행하면 비로소 화면이 그려집니다. 이후 사용자가 다른 페이지로 이동하면, 브라우저는 서버에 새 HTML을 요청하지 않습니다. JavaScript가 URL 변경을 감지하고, 해당 경로에 맞는 컴포넌트를 찾아 DOM을 직접 업데이트합니다. 이것이 클라이언트 사이드 라우팅입니다. 화면에 표시할 데이터가 필요하면 API 서버에 JSON을 요청하고, 받아온 데이터로 필요한 부분만 다시 그립니다. 이 구조에서 서버는 데이터를 주고받는 API 역할에 집중하고, 화면 렌더링과 사용자 인터랙션은 전부 브라우저 안에서 처리됩니다. 덕분에 페이지 전환이 빠르고 애플리케이션 상태가 유지되지만, 최초 JS 번들을 받아 실행하기 전까지는 사용자가 빈 화면을 보게 됩니다.
SPA와 SSR은 둘 다 웹 애플리케이션을 만드는 방식이지만, HTML을 어디서 만드느냐가 핵심 차이입니다. SPA는 브라우저에서 JavaScript로 화면을 생성하고, SSR은 서버에서 완성된 HTML을 보내줍니다. 이 차이가 만드는 결과는 분명합니다. SPA는 최초 로딩이 느릴 수 있지만 이후 화면 전환이 빠르고 상태 유지가 쉽습니다. SSR은 첫 화면이 빨리 보이고 검색 엔진이 콘텐츠를 읽을 수 있지만, 페이지를 이동할 때마다 서버가 다시 HTML을 만들어야 합니다. '어떤 게 더 좋은가'보다 '사용자가 이 앱을 어떻게 쓰는가'를 먼저 봐야 합니다. 로그인 후 복잡한 인터랙션이 주된 서비스라면 SPA가 자연스럽고, 검색 엔진에 노출돼야 하는 콘텐츠 중심 사이트라면 SSR이 낫습니다. 현실에서는 둘을 섞어 쓰는 하이브리드 방식도 흔합니다.
SPA는 로그인 뒤에 사용하는 관리 도구, 대시보드, 협업 앱처럼 사용자 인터랙션이 빈번하고 상태 유지가 중요한 서비스에서 가장 잘 맞습니다. 이런 서비스는 검색 엔진 노출이 크게 중요하지 않고, 한번 로딩된 뒤의 반응 속도가 사용 경험을 좌우합니다. 운영할 때 주의할 점은 JS 번들 크기입니다. 기능이 많아질수록 번들이 커지고, 초기 로딩 시간이 길어집니다. 코드 스플리팅으로 현재 화면에 필요한 코드만 나눠 로드하는 전략이 필수적입니다. SEO가 필요한 랜딩 페이지나 공개 콘텐츠에는 SPA 단독으로는 부족할 수 있습니다. 검색 봇이 JavaScript를 실행하지 못하면 빈 페이지만 인덱싱하기 때문입니다. 앱의 모든 페이지를 SPA로 만들어야 한다는 법은 없습니다. 공개 페이지는 서버에서 렌더링하고, 로그인 후 페이지만 SPA로 구성하는 방식이 실무에서 자주 쓰입니다.
더 깊게 보기
현재 페이지의 개념 설명을 본 뒤 공식 문서로 바로 이동합니다.