# Progressive Hydration 與 Streaming Server-Side Rendering
## 1. What is Hydration
儘管 Server-Side Rendering 已經有效改善 First Content Paint
但是不一定能提高好的 **Time To Interactive**

網站看似好了,但實際上「Buy Now」其實還沒辦法跟 User 互動(Interactive)
原因:因為 JavaScript 還沒好
-> 還沒被載入 or 還沒被處理
### 1.1 CSR

[reference](https://web.dev/rendering-on-the-web/)

[reference](https://blog.saeloun.com/2021/12/16/hydration.html)
### 1.2 SSR

[reference](https://web.dev/rendering-on-the-web/)

[reference](https://blog.saeloun.com/2021/12/16/hydration.html)
### 1.3 (Re)hydration 與恐怖谷(Uncanny valley)
```jsx=
// App.js
const App = (props) =>(
<button onClick={()=>alert(`Hi ${props.name}`)}>{props.name}</button>
)
// index.js
// CSR
ReactDOM.render(<App name="Ken"/>, document.getElementById('root'));
// SSR
ReactDOM.hydrate(<App name="Ken"/>, document.getElementById('root'));
// server.js
res.send(ReactDOMServer.renderToString(<App name="Ken" />)
```
> hydrate() is the same as render() but is used to hydrate a container whose HTML contents were rendered by ReactDOMServer. React will attempt to attach event listeners to the existing markup. [reference](https://blog.saeloun.com/2021/12/16/hydration.html)
#### hydration: 把 eventListener, handler 加到既有的 HTML Markup 上
hydrate 完成後,用戶才能跟網頁互動


[reference](https://zh.m.wikipedia.org/zh-tw/%E6%81%90%E6%80%96%E8%B0%B7%E7%90%86%E8%AE%BA)

[reference](https://www.therobotreport.com/our-relationship-with-the-uncanny-valley/)


### 有好感 -> 厭惡 -> 有好感
#### Ken 的解釋:有點太像,又有點不符合期待 -> 厭惡、排斥
### 1.4 hydration 的問題
1. 雖然可以很快看到畫面,但延後了使用者可以開始互動的時機
> (可能比使用者雖然晚看到、但能立即使用的體驗更差)
2. 高層次上的重複(見下圖)

### 1.5 解法
Progressive rehydration
Streaming server rendering
and etc...
## 2.Progressive Hydration


### 達成要素須滿足
1. 所有的 component 都能使用 SSR
2. 代碼分割(code splitting)可以下至一個 component 或更小的 chunk
3. 這些 chunk 在 client side 能依照開發者的定義的順序進行 Hydration
4. 不阻斷已 hydrated 完成的 user input
5. 當延遲的 Hydration 進行時,可以有某些指標 (loading) 來使用
#### React Concurrent mode 會直指、盡力實作滿足以上目標
1. lazy Suspense (declarative loading 指標與延遲載入)
3. Server Components (React Server Components 是透過網路請求來重新 render 他負責的子 Tree,可以結合其他既有的 Client Components 來保留 State。)[reference](https://chentsulin.medium.com/react-%E6%96%B0%E6%A6%82%E5%BF%B5-server-components-d632f9a18463)
但如各位所知,Concurrent 還在逐漸朝fully Production Ready 的路上
業界目前有 Partial hydration 可以使用,但 Partial hydration 也面臨一些實作、實務上的困難。

### Pros and Cons
1. 提倡、有助於代碼分割(code splitting)
2. 可根據需求、使用頻率決定載入
3. 有效降低 bundle size ,加速 FCP, TTI 的完成時間
----
## 3. Streaming Server-Side Rendering
### 3.1 What is streaming?

[reference](https://developpaper.com/how-to-use-grpc-stream-effectively-in-nodejs/)

[reference](https://ithelp.ithome.com.tw/articles/10221119)
#### 概念:同步拿取資料,但一次不要拿太大,分成小塊小塊的拿
### 3.2 與 React 的關係是...?
#### V16 版後,React 官方提供了 Stream 對應的 API
```jsx=
ReactDOMServer.renderToNodeStream(element) // (Deprecated)
ReactDOMServer.renderToStaticNodeStream(element)
```
`ReactDOMServer.renderToNodeStream(element)`(Deprecated) 效果等同於 `ReactDOMServer.renderToString(element)`
不過 output 會是 Node.js readablestream 的格式
讓 client 端透過 stream 不斷接收到小小 chunk 然後呼叫 hydrate
----
`ReactDOMServer.renderToStaticNodeStream(element)` 則對應於 `ReactDOMServer.renderToStaticMarkup(element)`
產出 HTML 的 stream 格式,可以用在非互動的靜態頁面上。


### Pros and Cons
1. 提升效能
2. Backpressure 的處理,可能使網站製作更具挑戰
3. stream 格式也被瀏覽器爬蟲所認可,可支持 SEO

## 4. Recap
#### 兩者的目標:都是希望加速 TTI 改善使用者體驗
#### 兩者的差別:一次「要」一點、一次 “讀”一點 (---vs---) 一次 “讀” 一點、一次 “讀” 一點



## 5. Reference
[web.dev: Rendering on the Web](https://web.dev/rendering-on-the-web/)
[Understanding Hydration in React applications(SSR)](https://blog.saeloun.com/2021/12/16/hydration.html)
[Hydration: Server-side rendering + Client-side rendering (下)](https://blog.timtnlee.me/post/development/ssr-hydrate-2)
[Joy 的 hackmd 筆記](https://hackmd.io/aCjbg0QtQrqCYoe_wugfBw)
[Emma 的 hackmd 筆記](https://hackmd.io/XSZKpM2-SwO-jwFhcVXmsw?view)
#### 導讀章節
1. [Patterns.Dev - Progressive Hydration](https://www.patterns.dev/posts/progressive-hydration/)
2. [Patterns.Dev - Streaming Server-Side Rendering](https://www.patterns.dev/posts/ssr/)