SSR and
web rendering
References
-
web rendering
- https://developers.google.com/web/updates/2019/02/rendering-on-the-web
- https://www.youtube.com/watch?reload=9&v=k-A2VfuUROg&ab_channel=GoogleChromeDevelopers
-
SSR, partial SSR
- https://medium.com/@luke_schmuke/how-we-achieved-the-best-web-performance-with-partial-hydration-20fab9c808d5
-
SSR 實作
- https://medium.com/%E6%89%8B%E5%AF%AB%E7%AD%86%E8%A8%98/server-side-rendering-ssr-in-reactjs-part1-d2a11890abfc
-
Others
- https://addyosmani.com/blog/rehydration/
Summary
- Summary of Web architecture and Page rendering
- About SSR
- Trade-off
- Different Hydrate Strategies
- Re-thinking of SSR
Summary of
Web architecture and Page rendering
MPA, SSR

https://caffeinecoding.com/universal-javascript-server-client-rendering/
SPA, CSR

CSR Drawbacks
- Long FCP (First Contentful Paint) time
- SEO
SSR + CSR

Universal Rendering
SSR with rehydration
...
- 結合了 SSR + CSR
- 是為了解決 SPA/純CSR 的一些 Drawbacks
It's More than "SSR"
About SSR
假設今天你有個 Single page application,
想要實作SSR, 你需要:
-
一個負責 SSR 的 server (rendering server)
-
根據不同的 path,讀取 SPA 的架構, pre-render components 然後 generate static 的 html
-
NodeJS (Js runtime)
// example with koa
import React from 'react';
import Koa from 'koa';
import Router from 'koa-router';
import path from 'path';
import fs from 'fs';
// import spa root component
import App from '../client/App';
// import function for SSR
import { StaticRouter } from 'react-router-dom';
import { renderToString } from 'react-dom/server';
const app = new Koa();
const indexTemplate = fs.readFileSync(path.join(__dirname, '../clientBuild/index.html'), 'utf-8');
app.get('(.*)', (ctx) => {
const result = renderToString(
<StaticRouter location={ctx.request.url}>
<App />
</StaticRouter>,
);
// should use index.html template
const html = indexTemplate.replace(/#{content}/, result);
ctx.body = html;
});
app.listen(3000);
A quick look of simple ssr server
<!DOCTYPE html>
<html lang="en">
<head>
/* meta */
<title>SSR Practice</title>
</head>
<body>
<div id="root">
/* Inject in here */
</div>
</body>
</html>
<div>
<h1>Home</h1>
<ul>
<li>Page1</li>
<li>Page2</li>
</ul>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
/* meta */
<title>SSR Practice</title>
</head>
<body>
<div id="root">
<div>
<h1>Home</h1>
<ul>
<li>Page1</li>
<li>Page2</li>
</ul>
</div>
</div>
</body>
</html>
1. spa index.html
2. server render string
3. result html
How it works
- Render it as an HTML string on the server
- Send the rendered HTML string to your users as source code (Static)
- Send your React or other code as JavaScript to your users
- And then finally “hydrate” your HTML using your React code (become interactive)
Hydrate
<!DOCTYPE html>
<html lang="en">
<head>
/* meta */
<title>SSR Practice</title>
</head>
<body>
<div id="root">
<div>
<h1>Home</h1>
<ul>
<li>Page1</li>
<li>Page2</li>
</ul>
</div>
</div>
</body>
</html>
ReactDOM.hydrate(<App />, document.getElementById('root'));
ReactDOM.render(<App />, document.getElementById('root'));
More things need to be Handled
- Css
- Route
- Redux
- Init Page Data
...
有興趣實作的可參考 系列文 和 溫故而知新—再談一次React Universal Rendering
Render server + SPA
= Universal JavaScript Application


SSG, pre-render
- Pages are static.
- Generate at build time


A Quick Look (NextJS)


使用 pages 這個頁面來定義
routing
在 page-level 檔案寫 React Component + SSR 邏輯
/post/test/first-post

Initial Page Data
Trade-off
You have fast First paint, but...

- Time to first Byte increase (compare to CSR)
- noninteractive before hydration
- events fire before hydration
Web Performance
- JS Bundle size
- Code Splitting
- CDN
- Encoding (Br, Gzip...)
- PWA, service worker cache
- Different Hydration strategies
Streaming server
http.createServer((request, response) => {
const html = ReactDOMServer.renderToNodeStream(<App />);
response.pipe(html);
}).listen(3000)
Different
Hydrate Strategies
Partial Hydration

example:
pool-attendant-preact
https://medium.com/@luke_schmuke/how-we-achieved-the-best-web-performance-with-partial-hydration-20fab9c808d5


Progressive Hydration
Pieces of the site are "booted up" in order of priority


- Only hydrate those are interactive
- Reduce JS bundle
- Improve hydration cost
Rethinking of SSR
SEO
only for crawlers that not support JavaScript
CSR negatively affect SEO

Improve SEO without full SSR
- title tag, meta tag
- Dynamic rendering
Spectrum
Server-side
rendering

Server-side
rendering
Client-side
rendering

Site App
Server-side
rendering
Client-side
rendering
SSR and CSR
Server-side
rendering
Client-side
rendering
pre-rendering
SSR w/
hydration

Server-side
rendering
Client-side
rendering
pre-rendering
SSR w/
hydration
- partial/progressive hydration
- streaming server
End
SSR
By Timothy Lee
SSR
- 509