###### 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 ![](https://i.imgur.com/MUM08d3.png) ![](https://i.imgur.com/WyKntmp.png) ## MPA - 指的是一般傳統開發方式, 一個畫面,一個 HTML 檔案 - Pros - SEO 可優化: 可針對每個頁面進行優化 - 分析能力: 每個頁面獨立, google容易分析每個頁面的性能 - Cons - 效能和速度: 每次都要reload pages - 前後端緊密整合: 開發跟測試需要較長時間 - 維護和更新: 要維護大量page與更新 - Examples - Amazon, eBay ## SPA - 把所有資料都放在同一個頁面,**不需要換頁**,使用者可以在單一頁面裡瀏覽全部內容,也就是說只會有一個index.html 檔 - 透過 AJAX 技術,client 可以向 server 發出非同步請求,索取局部內容的資料進行抽換,降低每次請求與回應的資料量,提高瀏覽速度 ![](https://i.imgur.com/w7ChyZO.png) - Pros - 效能優 - 使用者體驗優 - 開發速度快 - 容易debug - 數據可緩存: 向伺服器發出第一個請求後, 資訊緩存在catch, 較能有離線作業模式(GoogleDocs offline mode) - Cons - SEO問題: 初始頁面空的 - 下載內容時間: 如果平台複雜、龐大且優化不佳,用戶的瀏覽器要花很多時間來加載內容 - 需要JS的支持: 如果沒有此功能,您將無法完全使用某個應用程序的完整功能。如果用戶在瀏覽器中禁用 JS,他們將無法充分利用該應用程序 - Examples - Gmail, Twitter, Facebook, Google Maps, Evernote, Airbnb, etc. ## CSR ### Flow ![](https://i.imgur.com/ji3OZQ4.png) 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 ![](https://i.imgur.com/Jcf0pbo.png) 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)