SPA 이전의 역사로, SPA가 왜 등장했는지 알아보았다.
1. 일반적인 정적인 웹페이지
html
파일 여러개가 a
태그로 연결되어 있다.
url(href)이 파일 경로가 된다.
페이지 이동 시 새로고침이되면서 서버로부터 전체 파일을 다시 내려받는다.
웹 어플리케이션이라기 보다는 웹페이지의 구성이다.
만약, 게시판을 만든다고 생각하면 모든 게시글 마다 하나의 html이 필요하다.
2. 웹 어플리케이션
서버와 클라이언트에서 쓰는 언어가 다를 경우 같은 로직이지만 다른 언어로 반복하여 작성해야 하고, 똑같은 로직이더라도 버그가 발생할 수 있는 문제점이 있다.
UI를 생성하는 부분을 템플릿화하여 서버와 클라이언트에서 동일하게 쓸 수 있게끔 했지만 환경에 따라 동작이 100% 일치하지 않았다.
또, 궁극적으로 유저 인터랙션 처리(JS 이벤트 바인딩)은 클라이언트 사이드에서 해야하므로 결국 모든 처리를 서버에서 하는 것은 불가능하다.
3. SPA(Single Page Application)
SPA는 처음에 모든 파일을 다 불러오므로 초기 로딩 속도가 느릴 수 있다. 초기 로딩 속도 개선을 위해 비동기 로딩(페이지로 이동하거나, 마우스를 올리는 등 필요한 시점에 파일을 로딩)을 이용하여 해결할 수 있다.
https://localhost:5500/#detail -> detail 페이지로 이동
https://localhost:5500/#qna -> qna 페이지로 이동
locatin.hash
를 통해서 어떤 페이지를 렌더링할지 정하는 로직을 이용한다.cosnt { hash } = location;
if( hash === "" ) {
// 홈 페이지 렌더링
} else if (hash === "qna") {
// qna 페이지 렌더링
}
...
단점
https://localhost:5500/#detail/?id=1
-> hash 값을 제대로 읽어오지 못하게 됨
https://localhost:5500/?id=1/#detail
-> 이상한 형태로 쓸 수 있음
pushState
를 통해 쌓이게 되며, 뒤로 가거나 앞으로 갈 때 참고하여 이동한다.pushState
, replaceState
두 개의 함수로 화면 이동없이 현재 url을 업데이트 할 수 있다.pushState
: 세션 히스토리에 새 url 상태를 쌓는다.replaceState
: 세션 히스토리에 새 url 상태를 쌓지 않고, 현재 url을 대체한다. 즉, 현재 url은 세션 히스토리에서 사라진다. (ex. 뒤로가기 하면 안되는 상황, form 처리 이후) /#detail-1 -> /detail/1
location.pathname
을 통해서 어떤 페이지를 렌더링할지 정하는 로직을 사용한다.cosnt { pathname } = location;
if( pathname === "/" ) {
// 홈 페이지 렌더링
} else if (pathname === "/qna") {
// qna 페이지 렌더링
}
...
함수들
pushState(state, title, url)
state
: 다음으로 이동할 url에 전달할 값, history.state
로 가져올 수 있다.title
: 브라우저의 타이틀을 변경할 수 있지만 대부분의 브라우저에서 지원하지 않아 빈 문자열을 넣는다.url
: a
태그를 클릭하거나, location.href
로 url을 변경하는 것과 다르게, 이 url이 변경된다고 해서 화면이 리로드되지 않는다.replaceState(state, title, url)
주의 사항
만약 페이지를 새로고침(리로딩)하게 되면 서버가 해당하는 html 파일을 찾고, 404 Not Found를 뱉을 수 있다. 따라서 어떤 url을 요청하든 서버가 index.html을 주도록 해야한다. 이러한 옵션은 아마존에도 있고, 로컬에서는npx serve -s
로 가능하다.
실습을 따라치면서 this 바인딩이 어떻게 되는지 아직도 모호한 부분이 있었다. 이것이 더 상위로 가는가 해당 함수로 가는가... 자바스크립트의 함수는 도대체 무엇인가(왜 클래스처럼 동작할 수 있는가?)...
자바스크립트에 대한 이해가 부족한 게 큰 것 같다. 차근차근 채워나가야지!💨