SPA

Single Page Application

개념

문서 하나를 받아 두고 이동할 때마다 그 안에서 화면만 갈아 끼우는 웹 구현 방식입니다.

등장 배경

예전 웹에서는 링크를 누를 때마다 서버에서 문서를 새로 받아 화면 전체를 다시 그렸습니다. 주소가 바뀌면 지금 보고 있던 것은 버려지고 새 문서가 처음부터 그려집니다. 문서 여러 장을 읽는 사이트에서는 이 방식이 자연스럽습니다.

문제는 한 화면에서 오래 일하는 도구에서 드러났습니다. 문서 목록에서 한 건을 열었다가 다시 목록으로 돌아오면 목록이 처음부터 다시 그려지고 스크롤이 맨 위로 올라갑니다. 방금 스무 번째 항목을 보고 있었는데 되돌아오면 첫 항목 자리입니다. 하루에 목록과 문서 사이를 서른 번 왕복하는 사람은 서른 번 기다리고 서른 번 다시 스크롤합니다.

더 나쁜 것은 화면이 통째로 바뀌면 그 화면에 있던 것이 함께 사라진다는 점입니다. 입력하다 만 댓글, 접어 둔 패널, 방금 고른 필터가 전부 초기값으로 돌아갑니다.

SPA는 문서를 한 번만 받아 두고 그 안에서 필요한 부분만 바꾸는 방식입니다. 기다림과 잃어버림이 같은 원인에서 나왔으니 그 원인을 없앤 것입니다.

작동 방식

처음 한 번 문서와 코드 묶음을 받아 두고, 그다음부터는 화면에 필요한 데이터만 받아 이미 떠 있는 화면을 고칩니다.

다섯 자리로 나눠 보면 이렇습니다.

  1. 첫 진입. 거의 빈 문서와 자바스크립트 묶음을 받습니다. 화면을 그리는 일이 전부 그 묶음 안에 들어 있기 때문에 묶음이 크면 첫 화면이 뜨기까지 오래 걸립니다. 이 방식이 내는 대가가 여기 몰려 있습니다.
  2. 이동. 주소가 바뀌어도 서버에 문서를 다시 요청하지 않습니다. 브라우저 주소만 바꿔 치고 어느 화면을 그릴지는 받아 둔 코드가 정합니다.
  3. 데이터. 화면마다 필요한 값만 따로 요청합니다. 목록으로 돌아올 때 이미 받아 둔 값을 다시 쓰면 기다림이 아예 없습니다.
  4. 상태. 화면을 갈아 끼워도 메모리에 있는 값은 그대로 남습니다. 입력 중인 내용과 스크롤 위치와 열어 둔 패널이 유지되는 것이 이 값 덕분입니다.
  5. 뒤로 가기와 새로고침. 브라우저가 알아서 해 주던 일을 직접 맡아야 합니다. 뒤로 가기를 눌렀는데 아무 일도 일어나지 않거나 엉뚱한 화면으로 가는 사고가 이 자리에서 납니다.

그리는 자리를 가르는 말들과 섞이기 쉬운데, 브라우저에서 화면을 그리는 클라이언트 렌더링과 같은 말이 아닙니다. 이쪽은 이동을 어떻게 하느냐의 구분이고 그쪽은 어디에서 그리느냐의 구분입니다.

요즘은 둘을 섞어 씁니다. 첫 화면은 서버가 미리 그려 내려보내 빈 화면을 없애고, 그 뒤의 이동은 SPA 방식으로 처리하는 식입니다. 서버가 그려 내려 주는 서버 렌더링과 이 방식이 만나는 자리에서 하이드레이션이 필요해집니다. 화면은 이미 보이는데 받아 둔 코드가 아직 동작을 입히지 못한 몇백 밀리초가 그 구간입니다.

쓰이는 곳

한 화면에 오래 머물며 조작이 많은 도구가 이 방식의 자리입니다. 문서 편집기, 관리자 화면, 숫자를 이리저리 돌려 보는 대시보드가 그렇습니다. 여기서는 이동이 잦고 잃으면 안 되는 상태가 많아서 얻는 것이 대가보다 큽니다. 하루에 목록과 문서를 서른 번 오가는 사람에게는 첫 진입의 1.6초를 한 번 치르고 나머지 스물아홉 번을 아끼는 셈입니다.

로그인한 뒤의 화면도 대개 이쪽으로 갑니다. 검색 결과에 뜰 필요가 없는 자리라 첫 화면이 조금 늦는 것을 감당할 수 있습니다.

반대로 맞지 않는 자리가 둘입니다.

첫째는 검색으로 사람이 들어와야 하는 페이지입니다. 이 방식은 거의 빈 문서로 시작하니 내용이 코드가 돌아간 뒤에 생깁니다. 수집기가 그 뒤까지 기다려 주지 않으면 빈 페이지로 읽힙니다. 이럴 때는 배포 전에 미리 만들어 두는 정적 생성이나 서버 렌더링을 씁니다.

둘째는 한 장만 보고 나가는 페이지입니다. 코드 묶음을 받는 값을 회수할 이동이 없으니 대가만 치릅니다.

페이지덱은 이 둘을 갈라 뒀습니다. 로그인 뒤의 문서 편집 화면과 관리자 화면은 SPA로 만들고, 공개된 문서 페이지와 블로그는 서버에서 그려 내려보냅니다.

실무 용례

"목록으로 돌아올 때마다 다시 로드돼요. 이게 왜 이러죠?"

받아 둔 데이터를 다시 쓰지 않고 매번 새로 요청하고 있다는 뜻입니다.

"첫 화면까지 3.2초인데 묶음이 1.4메가입니다."

이 방식이 치르는 대가가 감당할 수 있는 선을 넘었다는 지적입니다.

"이 페이지는 검색에 걸려야 하니 이 방식으로 두면 안 됩니다."

같은 제품 안에서도 페이지마다 다른 방식을 쓴다는 판단입니다.

페이지덱에서 태오가 문서 편집 화면의 첫 진입 시간을 재 보니 3.2초였습니다. 묶음 하나에 편집기와 관리자 화면과 통계 화면의 코드가 모두 들어 있었기 때문입니다.

화면별로 묶음을 쪼개 필요할 때만 받아 오게 고쳐 1.6초로 내렸습니다. 민서는 그 사이에 보이는 화면도 함께 정했습니다. 코드가 도착하기 전 0에서 1.6초 동안 무엇이 보일지가 정해져 있지 않으면 빈 화면이 그대로 노출됩니다.

흔한 오해

이 방식이 곧 빠른 방식이라고 보는 경우가 가장 많습니다. 화면이 깜빡이지 않고 넘어가는 느낌이 강해서 그렇게 읽힙니다. 그러나 빨라지는 것은 두 번째 이동부터이고 첫 화면은 오히려 느려집니다. 코드 묶음을 다 받아야 첫 그림이 나오기 때문입니다. 이 구별을 놓치면 첫 화면이 3초인 제품을 빠르다고 보고하게 되고, 광고로 데려온 사람이 그 3초 안에 나가는 것을 설명하지 못합니다.

이 방식을 쓰면 서버 쪽 일이 줄어든다고 보는 오해도 흔합니다. 화면을 그리는 일이 브라우저로 넘어갔으니 그렇게 보입니다. 그런데 화면에 채울 데이터는 여전히 서버에서 오고, 요청이 화면 단위에서 값 단위로 잘게 쪼개져 오히려 늘어납니다. 화면 단위로 스무 건이던 요청이 값 단위로 예순 건이 되는 일이 흔합니다. 검색에 걸려야 하는 페이지와 메신저에 링크를 붙였을 때 뜨는 미리보기도 서버가 그려 줘야 합니다. 줄어든 것이 아니라 서버가 하는 일의 종류가 바뀐 것입니다.

자주 헷갈리는 용어

용어무엇을 정하는가SPA와의 차이
PWA웹을 앱처럼 쓰게 하는 형태설치와 알림과 오프라인 동작을 더한 껍데기 쪽 이야기입니다. SPA는 화면을 어떻게 갈아 끼우는지를 정하는 쪽이라, 둘은 겹쳐서 성립합니다

같이 보면 좋은 페이지

마지막 업데이트 2026-09-26