###### tags: `Web`
# [Web] Compare muti & single page application (MPA v.s SPA) and client-side & server-side render (CSR v.s SSR)
## Outline
- Muti Page Application (多頁面應用程式)-> MPA
- Single Page Application (單頁面應用程式)->SPA
- Client Side Render (客戶端渲染)->CSR
- Server-Side Render (伺服器端渲染)->SSR
## MPA v.s SPA


## MPA
- 指的是一般傳統開發方式, 一個畫面,一個 HTML 檔案
- Pros
- SEO 可優化: 可針對每個頁面進行優化
- 分析能力: 每個頁面獨立, google容易分析每個頁面的性能
- Cons
- 效能和速度: 每次都要reload pages
- 前後端緊密整合: 開發跟測試需要較長時間
- 維護和更新: 要維護大量page與更新
- Examples
- Amazon, eBay
## SPA
- 把所有資料都放在同一個頁面,**不需要換頁**,使用者可以在單一頁面裡瀏覽全部內容,也就是說只會有一個index.html 檔
- 透過 AJAX 技術,client 可以向 server 發出非同步請求,索取局部內容的資料進行抽換,降低每次請求與回應的資料量,提高瀏覽速度

- Pros
- 效能優
- 使用者體驗優
- 開發速度快
- 容易debug
- 數據可緩存: 向伺服器發出第一個請求後, 資訊緩存在catch, 較能有離線作業模式(GoogleDocs offline mode)
- Cons
- SEO問題: 初始頁面空的
- 下載內容時間: 如果平台複雜、龐大且優化不佳,用戶的瀏覽器要花很多時間來加載內容
- 需要JS的支持: 如果沒有此功能,您將無法完全使用某個應用程序的完整功能。如果用戶在瀏覽器中禁用 JS,他們將無法充分利用該應用程序
- Examples
- Gmail, Twitter, Facebook, Google Maps, Evernote, Airbnb, etc.
## CSR
### Flow

1. Client side 發出 request, sever 回傳幾乎不含任何內容的html
2. 瀏覽器 load JS bundle
3. 瀏覽器執行 React, fetch API 拿到 DATA,React 更新 UI
4. 頁面完整呈現且可互動
### Feature
- 畫面於 Runtime 時,==在 Client 製作==
- User 可以很快看到畫面,但畫面並非一次到位,而是批次到位,ex: 畫面顯示 loading 狀態
- 效能主要來自使用者身上,伺服器可以專心做資料處理負擔降低很多
### Code Example
Special Function: `useEffect`
```javascript=
// React.js
export default function CSRPage() {
const [dateTime, setDateTime] = useState();
useEffect(() => {
axios
.get('http://worldtimeapi.org/api/timezone/Asia/Taipei')
.then((res) => {
setDateTime(res.data.datetime);
})
}, []);
return (
<main>
<div>{dateTime}</div>
</main>
);
}
```
### Pros
- 頁面資料是最新的:每次頁面請求會在 Client side 打 API 取得最新資料
### Cons
- SEO較差:HTML 檔案只有容器,內容透過 JS 後來才渲染的,爬蟲在爬取資料時可能會爬到空的 tag
- 需要靠 JS fetch data + render 頁面,所以 JS bundle較大,隨著專案擴充容易有效能問題
## SSR
### Flow

1. 當user進入頁面, client 向 server 發出 requests, 此時畫面才開始在 server 端製作,Build 出一個擁有完整內容的 HTML 檔案(含 React js css 以及 DATA)
2. client 端 browser load html, css, js file
3. 進行 Hydration, 在 Client 端把 Server 端渲染出的 DOM element 加上事件監聽器等屬性,讓 DOM element 變為動態且具有互動性
4. 頁面完整呈現且可互動
### Feature
- 畫面於 Runtime 時,==在 Server 製作==,當畫面製作完成傳回 Client 後才會 render
- 發出請求後到**看到畫面會有點小 delay,User 需要等待才會一次看到完整畫面**(不會有 Loading 指標)
### Code Example
- Special Function: `getServerSideProps`
- `getStaticProps` 會在執行 npm run build 的時候執行並抓取所需要的資料。伺服器跑完該 function 後,除了產生了 HTML 檔案,會另外產生 JSON 檔案。在 Client-side 瀏覽器會讀取該 JSON 檔案裡面的資料用來顯示 page 內容
- 每次 Client-side 發出 request 的時候在 Server side 執行, 產生html檔給Client-side show畫面 [demo](https://www.patterns.dev/posts/server-side-rendering/)
```javascript=
// Next.js
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
}
}
export default Blog;
```
### Pros
- SEO優:在 Server 就製作好畫面,爬蟲爬到的是在 Server 建好並帶上完整資訊的 HTML 檔案
- 不需要使用 JS 來處理 render 頁面的部分,較不會造成 render blocking,JS 檔案較小
### Cons
- TTFB (Time to First Byte) 指標差,下列情形會導致 Server 的回應更慢:
- 網速慢
- 有大量 User request,sever 要夠強大
- Sever 端寫的程式碼太糞
## CSR V.S. SSR compare demo
- [CSR demo](https://theodorusclarence.com/blog/nextjs-fetch-method#demo)
- [SSR demo](https://theodorusclarence.com/blog/nextjs-fetch-method#demo-1)
## 總結
- CSR 通常是在講 SPA 居多
- SSR 通常是在講 MPA 居多
## Reference
[Multi-page Application](https://lvivity.com/single-page-app-vs-multi-page-app)
[Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR)](https://theodorusclarence.com/blog/nextjs-fetch-method#introduction)
[getStaticProps](https://nextjs.org/docs/basic-features/data-fetching/get-static-props)