初探 React Server Side Rendering(SSR) & 課程筆記

Harry Xie
6 min readApr 25, 2021

--

前言

本篇文章簡單介紹了 Server Side Rendering 並記錄了 Udemy 上的 Server Side Rendering with React and Redux 課程筆記,希望讓讀者對 SSR 有初步認識外,也讓自己對於課程內容進一步融會貫通。

為什麼需要 Server Side Rendering ?

在學習一個技術前,都要了解為什麼要學它?以及它有什麼作用?因此這裡就簡單介紹這個技術的特色、優缺點。

在做 CSR (Client Side Rendering) 時,我們必須等待 JS 檔案(最常見的就是 webpack 編譯出來的 bundle.js)傳到瀏覽器端後才開始渲染畫面,如此一來必須花費比 SSR 更多的時間去渲染畫面,若 JS 檔案更大想必花費更多時間,並且有些資料來不及載入時搜尋引擎就先進行爬蟲了,這樣就會導致不利 SEO

SSR 的優點就是解決了 CSR 的兩項缺點,以下是 SSR 的運作流程:

  1. 使用者進入某使用 SSR 的網站
  2. Server 端收到 http 請求,開始載入所需資料
  3. Server 端產生 HTML 發送到 Client 端(瀏覽器端)
  4. HTML 內需要載入 JS 檔案或其他檔案(bundle.js、JSON…)
  5. Server 端又收到請求,處理完成後發送到 Client 端

至於如何在 Server 端做渲染,便是透過一個叫 renderToString() 的函式包著元件,渲染結束後會返回 HTML 字串。

課程內容記錄

接下來的部分就是針對課程提到的內容做一些重點式的紀錄。

ReactDOM.hydrate()

在 Server 端時傳回的 HTML 是純畫面呈現,若要為它增加事件監聽(ex: onClick)就是使用這個函式。

StaticRouter

在 server 端要使用 SSR 的話,要用 StaticRouter,因為使用 BrowserRouter 的話,會根據 address bar 的 url 去呈現畫面,但 SSR 無法看到 address bar。

那無法看到 address bar 要如何知道目前的 url?

  1. req 裡面有 path 屬性
  2. 不再使用 express.js 去辨別路由,而是透過 react router 去辨別,因此在寫 api 的部分使用可以代表全部路徑的 * (app.get(‘*’)…)

處理 SEO

課程中使用了 react-helmet 套件,功用是可以在不同的頁面中動態的變更 <head> 標籤內的資訊,以下是程式範例:

import React from 'react';
import { renderToString } from 'react-dom/server';
import express from 'express';
import App from './src/App';
const app = express();

app.get('*', (req, res) => {
const app = renderToString(<App />);
const helmet = Helmet.renderStatic();

const html = `
<!doctype html>
<html ${helmet.htmlAttributes.toString()}>
<head>
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
</head>
<body ${helmet.bodyAttributes.toString()}>
<div id="app">
${app}
</div>
</body>
</html>
`;

res.send(html);
});

app.listen(3000);

比較 renderToString() vs. renderToNodeStream()

renderToString() 是盡可能地快點回傳 HTML,且是一次性回傳,在效能方面雖然花費比較多 TTFB,但回傳速度較快。

renderToNodeStream() 則是一小包一小包陸續的回傳 HTML,雖然回傳全部資料會花比較多時間,但 TTFB 花的時間比較短。

TTFB (Time To First Byte)

指網路請求發出(使用者點擊某網址的那瞬間)到接收從伺服器傳回的一個字節的這段時間。

心得

此課程也有介紹到 SSR 加入 redux 會碰到的各種問題及解決辦法,做了許多的設定…理解到不用框架去做 SSR 的缺點是邏輯架構變得相當複雜,花費更多時間處理,需要寫很多的程式在 server & client 做處理,例如像這種錯誤:

發生原因就是 server 和 client 渲染的內容需一致,如附圖一個渲染 input 另一個渲染 textarea 就會出錯,而這只是處理 SSR 的一環…

之後打算來接觸 Next.js,若有心得會再補充在本文哩~

若這篇文章對你有幫助,不妨鼓鼓掌支持一下,謝謝!

--

--

Harry Xie

專注於網頁技術的鑽研,認為「有熱情持續自我學習、提升技能」、「重視團隊流暢溝通與開發前的規劃」、「擁有獨立解決問題的能力」是成為優秀工程師的重要能力。更多關於我 : https://linktr.ee/harry.xie