쑤쑤_CS 기록장

37. Single Page Application & Routing 본문

IT 지식 기록/JavaScript 정리

37. Single Page Application & Routing

(╹◡╹)_ 2020. 12. 28. 18:12
728x90

#1. SPA(Single Page Application)

단일 페이지 애플리케이션(Single Page Application, SPA)

  • 모던 웹의 패러다임
  • 단일 페이지로 구성되며 기존의 서버 사이드 렌더링과 비교할 때, 배포가 간단하며 네이티브 앱과 유사한 사용자 경험을 제공할 수 있다.
  • 웹 애플리케이션에 필요한 모든 정적 리소스를 최초에 한번 다운로드 한다. 이후 페이지 갱신에 필요한 데이터만을 전달받아 페이지를 갱신단다.
  • 핵심 가치 : 사용자 경험(UX) 향상
  • 단점 : 초기 구동 속도, 검색엔진 최적화 문제

 

#2. Routing

라우팅

  • 출발지에서 목적지까지의 경로를 결정하는 기능
  • 사용자가 태스크를 수행하기 위해 어떤 화면에서 다른 화면으로 전환하는 내비게이션을 관리하기 위한 기능
  • 사용자가 요청한 URL, 이벤트를 해석하고 새로운 페이지로 전환하기 위한 데이터를 취득하기 위해 서버에 필요 데이터 요청하고 화면을 전환하는 행위

 

브라우저가 화면 전환하는 경우(3)

  • 브라우저의 주소창에 URL을 입력하면 해당 페이지로 이동한다.
  • 웹페이지의 링크를 클릭하면 해당 페이지로 이동한다.
  • 브라우저의 뒤로가기 또는 앞으로가기 버튼을 클릭하면 사용자가 방문한 웹페이지의 기록(history)의 뒤 또는 앞으로 이동한다.

history 관리를 위해서 각 페이지는 브라우저의 주소창에서 구별할 수 있는 유일한 URL을 소유하여야 한다.

 

#3. SPA Routing

#3.1 전통적 링크방식

  • link tag로 동작
  • 기본적인 웹페이지의 동작 방식

  • 장점 - JavaScript가 필요없이 응답된 html만으로 렌더링이 가능하며 각 페이지마자 고유의 URL이 존재하여 history 관리, SEO 대응이 가능
  • 단점 - 중복된 리소스를 요청마다 수신해야 하며, 전체 페이지를 다시 렌더링 하는 과정에서 새로고침이 발생하여 사용성이 안좋음
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Link</title>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="service.html">Service</a></li>
      <li><a href="about.html">About</a></li>
    </ul>
  </nav>
  <section>
    <h1>Home</h1>
    <p>This is main page</p>
  </section>
</body>
</html>

 

서버 렌더링

  • 서버는 html로 화면을 표시하는데 부족함 없는 완전한 리소스를 클라이언트에 응답한다
  • 브라우저는 서버가 응답한 html을 수신하고 렌더링한다

#3.2 Ajax 방식

  • 전통적 링크 방식은 요청마다 중복된 HTML, CSS, JavaScript를 매번 다운로드해야 하므로 속도 저하의 요인이다.
  • 자바스크립트를 이용해서 비동기적으로 서버와 브라우저가 데이터를 교환할 수 있는 통신 방식

  • 장점 - 불필요한 리소스 중복 요청 방지, 갱신이 필요한 일부만 로드하여 갱신
  • 단점 - URL을 변경시키지 않아 주소장의 주소가 변경되지 않음, history 관리가 동작 안함
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>AJAX</title>
  <link rel="stylesheet" href="css/style.css">
  <script src="js/index.js" defer></script>
</head>
<body>
  <nav>
    <ul id="navigation">
      <li><a id="home">Home</a></li>
      <li><a id="service">Service</a></li>
      <li><a id="about">About</a></li>
    </ul>
  </nav>
  <div class="app-root">Loading..</div>
</body>
</html>

 

 

#3.3 Hash 방식

  • Ajax방식은 history 관리가 되지 않는다.
  • URI의 fragment identifier(#service)의 고유 기능인 앵커(anchor)를 사용

  • 장점 - hash는 변경되어도 서버에 새로운 요청을 보내지 않고 페이지가 갱신되지 않음, 고유의 URL이 존재하므로 history 관리 가능
  • 단점 - SEO 이슈. 크롤러는 JavaScript를 실행시키지 않기 때문에 사이트의 콘텐츠 수집 불가능
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>SPA</title>
  <link rel="stylesheet" href="css/style.css">
  <script src="js/index.js" defer></script>
</head>
<body>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="#service">Service</a></li>
      <li><a href="#about">About</a></li>
    </ul>
  </nav>
  <div class="app-root">Loading...</div>
</body>
</html>

 

 

#3.4 Pjax 방식

  • hash 방식은 SEO 이슈가 있다.
  • HTML5의 History API인 pushState와 popstate이벤트를 사용

  • 장점 - 주소창의 URL을 변경하고 URL을 history entry로 추가하지만 요청하지는 않음, SEO 문제 없음
  • 단점 - 서버 렌더링 방식과 AJAX 방식이 혼재되어 있음, setRequestHeader 메서드를 사용하여 응답될 데이터의 mine type을 json으로 지정함
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>PJAX</title>
  <link rel="stylesheet" href="css/style.css">
  <script src="js/index.js" defer></script>
</head>
<body>
  <nav>
    <ul id="navigation">
      <li><a href="/">Home</a></li>
      <li><a href="/service">Service</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
  <div class="app-root">Loading...</div>
</body>
</html>

 

 

#4. 결론

애플리케이션의 상황을 고려하여 적절한 방법을 선택한다.

 

728x90
Comments