Hi!這裡是 Jing Tech 前端技術週報!除了 Substack 電子報外,也可以在筆者的部落格 jing-tech.me 與 instagram: jing.tech 關注前端大小事!
本週深度閱讀
React Server Components
React Server Components 無疑的是 2023 年 React 生態系中最讓人振奮的議題,相信 2024 年會有越來越多應用使用 RSC, 但我們不訪可以看一下 React 從 CSR 到 RSC 這個過程當中的演變與歷程,以及為什麼又會有 RSC 的出現。
CSR (Client Side Rendering)
回想在筆者 2018 年在學習 React 時,需要建立專案就是在終端機下 npx create-react-app app 等個兩三分鐘下載資源,再來 npm start 開啟應用,最後就是一個熟悉的
React Icon 出現在頁面上。
create-react-app
可以很快速的建立客戶端渲染的 React 應用,應用裡的任何邏輯,像是 UI、資料請求與處理等等的邏輯,經過打包後都會被放到 bundle.js 內,而最終打包後的 HTML 就會像是這樣:
// dist/index.html
<!DOCTYPE html>
<html lang="en-US">
<body>
<div id="app"></div>
<script src="/dist/bundle.js"></script>
</body>
</html>
當使用者訪問網站時,瀏覽器首先加載 dist/index.html,並開始下載並解析 bundle.js。解析完成後,React 開始構建應用的 DOM 結構,並插入到 <div id="app"/>
, 這就是 CSR 的渲染方式。
而這個方式最大的缺點就是會有首幀白屏過久的問題,這大幅的影響用戶體驗,因為我們需要等 JS 解析與 React 建構完成後才能看到畫面。
SSR (Server-Side Rendering)
預渲染 (Pre-rendering)
畢業後進入的第一間公司,也是用 CSR 的方式渲染頁面,但時不時就會收到產品與用戶端的反饋說頁面的載入時間太久了,也就是首幀白屏過久的問題。
而那時候發現有個解決方案就是預渲染 Pre-rendering,像是使用 react-snap 等套件,先在建構時產出一份頁面的骨幹,而瀏覽器加載的 HTML 是一個有骨幹而不是空白。
雖然解決首幀白屏過久的問題,但使用者一樣需要等資料撈取的時間,那有沒有方法讓HTML 載入完成的同時,資料也都呈現在畫面上了,也就是資料撈取也在伺服器處理好。
Meta (Server) Framework
舉凡像是 NextJS、Gatsby 與 Remix,它們都屬於開源的 Meta Framework,也就是在 React 這個 UI 庫上加入資料管理、路由管理等等功能的應用框架。當然也有部分公司是自己打造 Meta Framework。
而這些 Framework 的共通點都是支援伺服器端的資料獲取,讓伺服器收到請求時,就會直接在伺服器端先將資料進行獲取並進行渲染,當瀏覽器加載的 HTML 的時候就是一個完整的頁面。
儘管送到頁面的 HTML 是完整的,解決了首幀白屏問題,但這時候網頁是不可互動的,原因就是頁面需要 React 為它注水,稱為水合 (hydrate),這階段 React 會將所有的事件邏輯綁定到組件上面。當應用大到一定的程度時,邏輯也會一起肥起來,React 就需要花越多時間去進行水合,在這過程中頁面就像壞掉了一樣,任何與頁面的互動皆不會有反應,也被稱為 Uncanny Valley。
Streaming Rendering
接著 Streaming Rendering 解決了上述的問題,將 HTML 切成一小塊的方式回傳到前端,這時 JavaScript 能夠同時進行解析(parse)和渲染這些小塊的 HTML,而不必等待整個 HTML 文檔下載完畢。這種方法提高了頁面加載的效率,因為它允許瀏覽器更早地開始渲染過程。
React Server Component (RSC)
RSC 則是把腦筋動到資料獲取 (Data Fetching) 身上,相較於 Meta Framework 所有的伺服器端的資料獲取只能在頁面層級進行,RSC 則是將伺服器端的資料獲取縮小到組件層級,這也使得它們多了一些限制,例如與現在 React 一些既有的 API 不相容,沒辦法進行重新渲染等等。
RSC 也不會被包在 bundle.js 裡面,而是在 HTML 裡加入 RSC Payload 類似 JSON 的資料結構,這使得瀏覽器在加載 JavaScript 時的體積變小,但同時需要搭配打包工具才能達到此效果,也因為要讓打包工具知道哪些是 RSC 才會需要在檔案裡標記 use server 或是 use client
。
相較於從 CSR、SSR 到 Streaming,RSC 是另外一種概念,兩者也可以同時使用,只是它讓開發者有了多了一個選擇讓程式碼可以不要加入到 bundle 中,進而讓 bundle 的體積減少,提升用戶體驗。
但此同時開發者需要用不同的思維去學習它,至今筆者依然不是很懂,或許找時間做個 Side Project 讓把自己的手用髒後,再來分享!
以上只是筆者看完的一些感想,也非常推薦大家閱讀該篇深度閱讀的文章,非常精彩!
本週熱點與選讀
文章
React Server Components: the Good, the Bad, and the Ugly
上週在 Twitter 上看到 Redux 維護者 Mark 轉推了這篇文章,沒想到僅僅一週後就在 React 社群有著非常高的討論度,文章就如同標題所示主要是講到 RSC 帶來好、壞、醜以及更醜,非常推薦大家先看過與思考後,再看 Lee Robinson (VP of Product at Vercel) 回覆這篇文章的影片。筆者認為從 NextJS 發布 RSC 到現在其實也才一年左右的時間,不論是 DX、Dev Tool 以及文檔並沒有很完善,且 RSC 與 NextJS App router 對已經熟悉 React 的開發者來說確實需要花時間學習與習慣的。而以提升使用者產品體驗的角度來切入,RSC 確實是走在正確的道路。
More Than You Need to Know About ReactDOM.flushSync
這篇文章提供了一個互動式的介面讓讀者可以輕鬆地了解 React 是如何重新渲染的。也說明了在 React 18 加入了 Concurrent Mode 後,讓開發者能夠使用
ReactDOM.flushSync
選擇退出異步模式轉而使用同步模式 (de-opt to sync mode),通常是用在當狀態更新的時候需要立即使用 DOM API (e.g. scroll / focus…),可以透過flushSync
將更新能夠立即反映在用戶界面上。看完文章後可以看 React.dev - flushsync API 或是 Ryan Florence 的教學影片 來了解更多。這是 Dan Abramov 在近期發佈的第二篇部落格文章,闡述了 React 對於客戶與伺服器端 UI 的設計哲學,以客戶端來說
UI = f(state)
,在伺服器端則是UI = f(data)
,然而實務上更接近UI = f(data, state)。
最近在研究 Signal 的程式碼,發現了這篇文章很好的解釋了目前 preact/signal-core 核心的架構邏輯,文內也有說到 Preact 團隊原本使用資料結構 Set 去做依賴追蹤,但發現了 Set 在創建、重新排序依賴追蹤時會有產生效能問題,而 Linked List 正好可以解決上述的這些問題。
Let’s learn how modern JavaScript frameworks work by building one
作者認為現代的 JavaScript 框架應該要有三個要素,分別是 Reactivity 、 Cloned templates for DOM rendering 以及 modern web API (e.g. Proxy),並且透過這三個要素實作出一個簡單的 JS 框架。非常值得一看!
JavaScript Frameworks - Heading into 2024
文章回顧了 2023 年幾項重大進展,包括 Signals、Hybrid Routing 與 Edge Networks 開始受到關注和採用。作者還提到,2024 年將是一個整合的年份,前端領域將逐漸走向成熟,並更優化已經發掘的解決方案。例如,探索 Signal 更深層的潛力,以及隨著 Server-Side Rendering 越來越廣泛地被使用,這將進一步影響基礎設施的設計和配置,以及通用 AI 的發展。
影音
播客
Syntax 在這期講到他們對 2024 的前端生態圈的預測,從框架、基礎建設工具、CSS、TS 等等主題的進行預測,也可以了解現在前端發展未來大致的走向,非常適合在運動時收聽。
Lenny’s Podcast - The hierarchy of engagement | Sarah Tavel
這期 Lenny’s Podcast 邀請到了 Sarah Tavel,她是 Pinterest 第一位產品經理,在節目中 Sarah Tavel 談到了她對於 to C 的產品定義了三個層級。首先要了解產品的 Core Action,也就是當使用者做了什麼,才算是使用產品,像是 Pinterest 是點擊 Pin、YouTube 是點擊 Subscribe 以及 Evernote 則是建立筆記。知道產品的 Core Action 後,才能優化或改進它進而極大化 Retention,也就是讓使用者再次使用產品。除了上述兩個核心要素外,最後一個要素就是 Self Perpetuation,產品必須要自我延續,而網路效應 (Network Effect) 就是其中一個利器。Sarah 在 Podcast 舉了非常多例子,上面提到的也只是上半部的小部分內容,非常推薦大家可以聽完整期內容,會對於如何做產品有更深的了解。另外關於網路效應,想了解的話非常推薦曼報 Manny 的 Podcast - EP 51 | Network Effect。
本週 Jing Tech 新文章
這裡會列出近期 Jing Tech 部落格發布的新文章,與 Jing Tech 的技術週報不同,部落格中包含了更多的程式互動範例,讓讀者能夠更容易地理解和學習。非常歡迎讀者反饋與指教!
Design System 101 - Animation Presence
Design System 101 是筆者近期不斷更新的一個系列,主要深入探討一般大廠是如何實現 Design System 的,而 Animation Presence 是一個通用的組件,解決動畫與 React 卸載組件時之間的先後關係。
本期內容就更新到這裡,感謝大家的閱讀,如果有任何問題或想法歡迎一起討論,也歡迎分享給更多人知道!你的每一份支持,都是我持續創作的動力!更多關於我的創作可以點擊這裡。