💡 이번 프로젝트에서 어쩌다보니 Vue를 배워볼 일이 생겼는데 프론트를 제대로 접하기전에 CSR,SSR 개념을 확실히 알고가야 할 것같아 이번 기회에 제대로 알고가자!는 생각에서 포스팅을 작성하던 도중, MPA, SPA부터 이해하고 가야할것같아서 정리하게 되었다.
*MPA와 SPA
일반적으로 웹사이트에 접속하려면, 서버에게 HTML 파일에 대한 요청을 보낸다.
후에, 클라이언트는 어떠한 요청을 주게 되는데 위 사진에서 두가지의 차이점이 나타난다.
MPA방식은 HTML을 리턴하고있고, SPA는 JSON을 리턴하는 모습을 확인할 수 있다.
아래 사진을 보며 MPA을 먼저 살펴보자
* MPA(Multi Page Application)
위 사진에서 MPA방식은 요청이 들어올때마다 데이터와 페이지구조가 리로드되고, 컨텍스트(호출, 응답간의 환경 정보)가 사라지며, 무수한 요청을 HTML page에 담아리턴하는것을 확인할 수 있다.
여기서 중요한 점은 HTML page를 리턴한다는 점이다.
즉, 요청이 있을때 마다 페이지를 리로드한다.
아주 사소한 버튼 클릭도 매번 전체 페이지를 렌더링한다.
👉MPA의 장점
SEO(Search Engine Optimization, 검색 엔진 최적화) 관점에서 유리하다.
이말은 이미 완성된 형태의 HTML 파일을 서버에서 전달받기 때문에 검색엔진이 페이지를 크롤링하는데 유리하다.
👉 MPA의 단점
매번 페이지 전체를 새로 불러오기에 성능상 이슈가 있고, 프론트와 백이 밀접하게 연관되어 있기때문에, 개발 복잡도가 증가한다.
반대로 SPA를 살펴보자
* SPA(Single Page Application)
위 사진은 url에 따라 Header,Menu,Footer는 고정된채로 필요한 요소만 로드하고 있다.
즉, 전체 앱을 로드하는게 아닌 필요한 요소만 로드한다.
위 말을 생각해보면 MPA는 서버에서 완성된 페이지를 주는것과 달리 SPA는 그 일을 브라우저가 처리하고 있음을 알수있다.
어떻게 그게 가능하지?라고 의문이 들 것이다. 어떤 행위 자체는 서버에서 해야하는것 아닌가??
이게 가능한 이유는 JavaScript가 DOM을 건드릴 수 있는 script 언어이며, 웹 브라우저에 쓰이는 유일한 프로그래밍 언어이기 때문이다.
* DOM(Document Object Model) : HTML,XML 및 XHTML 문서의 프로그래밍 인터페이스로, 문서의 구조화된 표현을 제공한다.
단 하나의 index.html 파일(= Single Page)을 가지고 안의 내용물은 전부 .JS파일의 DOM 조작을 통해 채우게 된다.
처음 접한 사람은 위에서 2가지 의문이 들수있다.
1.프론트엔드에서 JavaScript로 데이터 베이스 연결은 어떻게 하나요?
2.하나의 HTML파일에서 어떻게 다른 페이지로 이동하나요?
HTML이 무조건 여러개여야 화면에서 보여지는것도 여러개 아닌가요?
하나씩 살펴보자
1.프론트엔드에서 JavaScript로 데이터 베이스를 어떻게 거치고 오나요?
위 해답은 REST API와 AJAX를 이용하는 것이다.
필요한 요소에 AJAX를 추가하여, URL을 호출한후, 데이터를 받아온다.
예제로 아래의 코드를 살펴보자.
function listing_Sleep() {
$('#cards-box').empty();
$.ajax({
type: 'GET',
url: '/main/asmr/sleep',
data: {},
success: function (response) {
let rows = response['ASMRs']
for (let i = 0; i < rows.length; i++) {
let comment = rows[i]['comment']
let title = rows[i]['title']
let content = rows[i]['content']
let thumbnail = rows[i]['thumbnail']
let url = rows[i]['url']
let temp_html = `<div class="col">
<div class="card h-100">
<a href="${url}"><img src="${thumbnail}"
class="card-img-top"></a>
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">${content}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>`
$('#cards-box').append(temp_html)
}
console.log(response['ASMRs'])
}
})
}
위는 부트캠프 당시에 진행했었던 미니프로젝트 ASMR 페이지의 코드중 일부이다.
중요한 부분은 $.ajax를 이용하여 type과url(REST API)를 호출하는 부분이다.
$.ajax({
type: 'GET',
url: '/main/asmr/sleep',
data: {},
success: function (response) {...}
})
GET타입으로 URL을 호출하여 AJAX로 통신하면 JSON으로 데이터가 내려오고, 해당 데이터를 통해 success내부에서 HTML을 재구성한다.
그 후, ajax가 포함된 함수를 특정 요소에 삽입한다.
success는 통신이 성공적으로 끝났을때 처리를 말하며 내부코드는 HTML을 구성해준다고 생각하면 된다.
보여지는 페이지를 예시로 들면 아래와 같다.
우측 아래에있는 Sleep 버튼에 위 함수를 연결해놓고, 해당 버튼을 클릭하면
페이지전체가 리로드 되는게아닌 빨간 네모안의 특정 요소부분만 재구성하여 리로드 된다.
즉, JavaScript로 REST API와 AJAX를 이용해 백엔드와 통신하여 데이터베이스를 거쳐 JSON데이터를 받아 특정 요소만 재구성하여 보여준다.
2.하나의 HTML파일에서 어떻게 다른 페이지로 이동하나요?
HTML이 무조건 여러개여야 화면에서 보여지는것도 여러개 아닌가요?
위는 라우터를 이용하면된다.
예를 들어, '/'에서 '/home'으로 갈때, 라우터가 해당 페이지로 이동시켜준다.
예시를 살펴보자.
<!DOCTYPE html>
<html>
<head>
<title>SPA Example</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/vue-router@4"></script>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script>
const Home = { template: '<div>홈 페이지</div>' };
const About = { template: '<div>소개 페이지</div>' };
const Contact = { template: '<div>연락처 페이지</div>' };
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/contact', component: Contact }
];
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
});
const app = Vue.createApp({});
app.use(router);
app.mount('#app');
</script>
</body>
</html>
위는 Vue.js를 사용하여 SPA를 구현한 코드이다.
코드를 간략하게 설명하자면,
1.routes에서 페이지 경로와 컴포넌트 간의 매핑을 정의하고,
2.createRouter()로 라우터 인스턴스를 생성하여 위에서 정의한 routes를 router 변수에 삽입한후
3.app.use(router)로 앱에 라우터를 등록한다.
복잡하다면 다 필요없고 아래 핵심만 기억하면된다.
하나의 HTML안에서 라우터로 인해 페이지간 이동이 일어난다.
기본적인 모든 정리는 끝났으니, 아래와 같이 A라는 사람이 SPA로 구성된 앱을 이용하는 시뮬레이션으로 마무리해보자.
👉 A가 SPA앱을 이용하는 시뮬레이션
1. A는 로그인을 마친후 마이 페이지 버튼을 클릭하였다.
2. 라우터를 통해 마이 페이지 URL로 이동한다. (= 모든 page는 index.html 단 하나에 담겨있다.)
3. A는 본인의 로그인 기록을 보기위해 기록확인 버튼을 눌렀다.
4. 기록확인 버튼에 연결되어있는 AJAX로 REST API로 요청을 보낸다. (= 프론트엔드는 AJAX로 통신한다.)
5. 서버(백엔드)는 REST API 요청을 받은후, 데이터베이스를 거쳐 해당 회원의 정보를 JSON으로 내려준다.
6. 브라우저에서는 전달받은 JSON을 가져와서, 새롭게 쓰여진 JavaScript로 요소를 재구성한다.
7. 페이지는 리로드 되지않은 상태로, 재구성된 요소들 즉, 기록확인 리스트가 노출된다.
* 참고자료
https://devowen.com/309
https://lvivity.com/single-page-app-vs-multi-page-app
'지식 저장소' 카테고리의 다른 글
등록 로직에서 dto를 Entity로 변환할때 변환하는 코드는 어디에? (0) | 2023.08.31 |
---|---|
JPA insert쿼리전에 select쿼리가 나가는 현상 ( feat.HHH000099 에러) (0) | 2023.08.28 |
같은 값 기준 정렬 후 페이징 시 목록 꼬임 문제 (0) | 2023.01.10 |
Replication(복제) (0) | 2022.09.08 |
Cannot add or update a child row 에러 (0) | 2022.01.19 |