[鐵人賽 2022-擊敗前端面試大作戰] client-side-rendering vs server-side-rendering
Client-side Rendering 客戶端渲染
Client-Side Rendering 指的是網頁渲染大部分都透過瀏覽器端來完成。所有的邏輯、取資料、路由等等都在瀏覽器裡處理。這樣的優點是整個網頁會在第一次渲染的時候完成,並且大部分的 UI 會在客戶端產生,所以當使用者換頁的時候,速度會很快使用者體驗會很好,因為大部分的架構不需要經過 server,都會是在客戶端完成。缺點則會有以下兩點:
- SEO 不好 CSR 在第一次跟 server 請求 HTML 時,HTML 檔案裡面幾乎沒有任何內容,是透過載入 JS bundle 再去把畫面 render 到 HTML 裡,因此速度上不一定能夠讓網路爬蟲可以索引到該網站。
//初始的HTML檔案
<html>
<head>
<link href="/static/css/main.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
</body>
<script src="/static/js/bundle.js"></script>
</html>
關於這部分的解釋我推薦這篇文章的解釋!
- 效能不好
CSR 會在 render 的時候 load 全部打包完的程式碼,當網頁變得越來越複雜功能越變越多,Javascript 檔案的大小也越變越大,造成網頁的 FCP 跟 TTI 都增加,代表使用者會在看到網頁之前,有一段時間是只有白頻的情況,造成使用者經驗不佳。
CSR 優化方法
打包 JS,把 JS 檔案縮小,
code splitting 避免出現一個檔案非常大的打包程式碼,透過 code splitting 把打包切分成不同的小檔案,來減少使用者在等待 render 時的畫面白頻的情況。
下面的例子,React 可以直接使用
import()
語法來使用 code splitting。
//Before code splitting
import { add } from "./math";
console.log(add(16, 26));
//After code splitting
import("./math").then((math) => {
console.log(math.add(16, 26));
});
- lazy loading
可以讓網頁只先 render 重要的部分,把比較不重要的資源等到要使用時再 load。同樣的,React 也有提供簡便的方式來達到 lazy loading,我們只要用
React.lazy
的語法,包住一個使用import()
語法的地方,就可以達到 lazy loading 的效果!
import React, { Suspense } from "react";
// lazy loading
const OtherComponent = React.lazy(() => import("./OtherComponent"));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
關於 React lazy loading, code splitting 額外的介紹,我推薦這篇文章
- 用 service worker 來使用快取頁面,讓後續的訪問讀取可以更快速,並且也提供離線訪問等功能。
Server-Side Rendering
當使用者透過 URL request 一個網站的時候,server 會處理 JS 和 HTML 再回傳一個完整的 HTML 給瀏覽器,所以瀏覽器只需要去解析該 HTML 就可以顯示畫面。
如果每當 client request 網頁時,server 都去重新生成 HTML,這種 SSR 就做 Dynamic Server Side Rendering。
SSR 的優點是,FCP(request 的內容第一次出現的時間)會比較快,因為 server 已經做完 render 的工作,並且會回傳完整的 HTML,可以直接解析,然後顯示在畫面上,節省掉解析 JS 的時間。也因次只要畫面顯示在頁面上,網站馬上就可以接受使用者的指令可以較快開始互動,TTI(網頁可以互動的時間)也會因此很快。除此之外,SEO 也會很好,因為 SSR 會產生完整的 HTML 給 browser,所以可以很容易的被爬蟲解讀。
SSR 的缺點主要有以下幾點:
- TTFB(Time To First Byte 的縮寫,顧名思義為從用戶端送出對伺服器的請求後,瀏覽器收到伺服器響應資料的時間)會比較慢,因為伺服器需要先生成完整的 HTML 後,再傳給瀏覽器。除此之外,如果同時有許多人造訪 server 或是使用者有緩慢地網速等等造成 server 負擔重的情況都會影響到 TTFB,換句話說,SSR 會對 server 比較大的影響。
- 互動性體驗差,因為 SSR 的頁面在每次互動之間都要重新在 server 重新讀取頁面,導致使用體驗跟網頁反應上不如 CSR 的頁面順暢。
統整一下,今天我們講了 CSR 跟他的優缺點還有如何去解決它的問題,並且我們還講了 SSR 跟其優缺點!下面就推薦給大家一個資源,有興趣的人可以自行去閱讀摟!
Static Site Generators
如果是在 build 的時候就預先生成好 HTML,等到有 request 時再回傳給 client,但因為回傳的是生成好的 HTML,所以缺點就是無法做 fetch/update 等的動作。
適合使用在靜態網站上!
推薦資源:https://www.patterns.dev/posts/static-rendering/
面試題:
- 什麼是 CSR?
- 什麼是 SSR?
CheatSheet
SSR
pros:
fast FCP,TTI(time to interactive)
cons:
slow TTFB(time to first bite, measures the duration from the user or client making an HTTP request to the first byte of the page being received by the client's browser. )
Static rendering
- producing a separate HTML file for each URL ahead of time.
- pre-rendered HTML content
pros:
fast FCP, TTFB
cons:
- individual HTML files must be generated for every possible URL
- not a ideal approach to large number of HTML files
- An SSG site needs to be built and re-deployed every time the content changes. The content displayed may be stale if the site has not been built + deployed after any content change. This makes SSG unsuitable for highly dynamic content.
Resources:
https://www.patterns.dev/posts/client-side-rendering/ https://www.patterns.dev/posts/server-side-rendering/ https://www.youtube.com/watch?v=k-A2VfuUROg https://reactjs.org/docs/code-splitting.html#reactlazy https://lidemy5thwbc.coderbridge.io/2022/01/29/CSR-SSR/ https://medium.com/@prashantramnyc/server-side-rendering-ssr-vs-client-side-rendering-csr-vs-pre-rendering-using-static-site-89f2d05182ef
https://blog.niclin.tw/2019/01/06/%E6%B7%BA%E8%BF%B0-ssr-spa-%E5%84%AA%E7%BC%BA%E9%BB%9E/ https://web.dev/rendering-on-the-web/
https://medium.com/@prashantramnyc/server-side-rendering-ssr-vs-client-side-rendering-csr-vs-pre-rendering-using-static-site-89f2d05182ef https://dev.to/matfrana/server-side-rendering-vs-static-site-generation-17nf
React with SSR https://www.digitalocean.com/community/tutorials/react-server-side-rendering