콘텐츠로 이동

전통적 MPA(Multi Page App)의 구조와 한계

웹의 시작: 문서를 주고받는 시스템

섹션 제목: “웹의 시작: 문서를 주고받는 시스템”

2005년 이전의 웹은 기본적으로 문서 배달 시스템 이었다. 브라우저가 URL을 요청하면, 서버가 HTML 문서를 만들어 응답하고, 브라우저는 그것을 화면에 표시한다. 그게 전부였다.

이 시기의 표준 아키텍처는 다음과 같다.

[브라우저] [웹 서버] [DB]
│ │ │
│── GET /products ──────────>│ │
│ │── SELECT * FROM ──>│
│ │<── rows ───────────│
│ │ (템플릿에 데이터 │
│ │ 삽입 후 HTML 생성)│
│<── 200 OK (완성된 HTML) ───│ │
│ (브라우저 전체 화면 갱신) │ │

링크를 클릭할 때마다, 폼을 제출할 때마다 이 사이클 전체가 반복된다. 매번 서버가 새 HTML을 생성하고, 브라우저는 화면 전체를 다시 그린다.

PHP, Java Server Pages(JSP), Django, Rails — 이 모두는 서버에서 HTML을 완성 해 클라이언트에 내려보내는 방식이다.

Django 템플릿 예시:

views.py
def product_list(request):
products = Product.objects.all()
return render(request, 'products/list.html', {'products': products})
{# products/list.html #}
<ul>
{% for product in products %}
<li>{{ product.name }} — {{ product.price }}원</li>
{% endfor %}
</ul>

서버가 데이터를 DB에서 읽고, 템플릿에 주입하고, 완성된 HTML 문자열을 응답으로 돌려준다. 브라우저는 그 HTML을 파싱해 화면을 그린다.

PHP의 경우:

<?php
$result = $db->query("SELECT name, price FROM products");
?>
<ul>
<?php while ($row = $result->fetch_assoc()): ?>
<li><?= $row['name'] ?> <?= $row['price'] ?></li>
<?php endwhile; ?>
</ul>

로직과 HTML이 한 파일에 뒤섞이는 형태였다. 간단하지만, 규모가 커질수록 유지보수가 어려워졌다.

쇼핑 카트에 상품을 추가하는 단순한 동작을 생각해보자.

<form method="POST" action="/cart/add">
<input type="hidden" name="product_id" value="42">
<button type="submit">장바구니에 추가</button>
</form>

버튼을 누르면:

  1. 브라우저가 POST /cart/add 요청을 보낸다
  2. 서버가 DB를 업데이트한다
  3. 서버가 302 Redirect/cart 페이지로 보낸다
  4. 브라우저가 GET /cart 요청을 다시 보낸다
  5. 서버가 장바구니 HTML 전체를 새로 생성한다
  6. 브라우저가 화면 전체를 갱신한다 — 스크롤 위치 초기화, 깜빡임 발생

이 “깜빡임”이 사용자 경험(UX)의 핵심 문제였다.

특성설명
단순성서버 한 곳에서 모든 로직을 처리
SEO 친화적완성된 HTML이 내려오므로 검색엔진 크롤링 용이
보안비즈니스 로직이 서버에만 존재
기술 스택 단일화Python/Java/PHP 하나만 알면 전체 개발 가능

2005년의 웹 사용 패턴은 주로 정보 탐색 이었다. 뉴스를 읽고, 상품을 검색하고, 이메일을 확인한다. 페이지 전환이 잦아도 사용자들은 그것을 당연하게 여겼다.

MPA의 한계 — 왜 변화가 필요했나

섹션 제목: “MPA의 한계 — 왜 변화가 필요했나”

인터넷 속도가 빨라지고 웹 앱이 복잡해지면서 문제가 드러났다.

한계구체적 문제
전체 페이지 리로드헤더/네비게이션 등 변하지 않는 영역도 매번 다시 전송·렌더링
서버 부하 집중모든 렌더링을 서버가 처리하므로 트래픽 급증 시 병목
반응성 한계드래그&드롭, 실시간 편집 등 앱 수준의 인터랙션 구현 어려움
대역폭 낭비내용 일부만 바뀌어도 전체 HTML을 다시 전송
상태 관리 불가페이지 이동 시 클라이언트 상태(스크롤, 입력값 등) 초기화

2004년 Gmail 등장이 전환점이었다. 이메일을 클릭했는데 페이지 전체가 깜빡이지 않는다. 답장을 쓰면서 다른 이메일을 탐색할 수 있다. 이것은 MPA 구조로는 불가능했다.

  • MPA(Multi Page Application)는 서버가 매 요청마다 완성된 HTML을 생성해 응답하는 구조다
  • PHP/JSP/Django 등 서버 사이드 템플릿 엔진이 이 방식의 핵심 기술이다
  • 모든 인터랙션이 전체 페이지 리로드를 유발해 앱 수준의 UX 구현에 한계가 있다
  • 2004~2005년 Gmail, Google Maps 등장으로 “웹도 앱처럼 동작할 수 있다”는 기대가 생겼고, 이것이 JavaScript 기반 동적 웹의 출발점이 되었다