前端架構演化史:每一站解決了什麼,又製造了什麼
文字解析 · 1 支影片 · 產生於 2026-10-01 00:54
章節(12)
1. Outline
- 起點 · Every Frontend Architecture Pattern Explained in 23 Minutes
把前端架構史講成一條被問題推著走的因果鏈:靜態頁面 → MVC → SPA → BFF → SSG/ISR/SSR/RSC → 模組化單體 → micro-frontend,每一站用同一張六軸卡片(擴展性、效能、複雜度、團隊規模、產品價值、成本)評分,最後收成一份可以照著跑的架構稽核。
2. YouTuber 的思維推導
Every Frontend Architecture Pattern Explained in 23 Minutes
theSeniorDev · 22m33s · 字幕 en · vision=on (使用者指定 vision=true;這支是投影片+白板型影片,每種架構都配一張示意圖與一張六軸評分表(擴展性/效能/複雜度/團隊規模/產品價值/成本),不看圖會漏掉整個比較基礎。) · YouTube
預估 vs 實際耗時
| 階段 | 預估 | 實際 |
|---|---|---|
| fetch | 6s | 1s |
| segment | 1m15s | 5m00s |
| shot | 50s | 6s |
| analyze | 10m00s | 15m00s |
| render | 5s | – |
作者的出發點是一個面試現象:被拒的人往往技術沒問題,只是講不出取捨,於是聽起來像中階。他的解法不是給一張「該用什麼」的對照表,而是把整個前端架構史講成一條被問題推著走的因果鏈——每一站都是為了解決上一站的痛點而生,而每一個解法又製造出下一站要解決的新痛點。靜態頁面快但沒互動,於是 MVC 把邏輯搬上伺服器;MVC 整頁重載又前後端緊耦合,於是 SPA 把邏輯搬進瀏覽器;SPA 送出太多 JavaScript、首屏空白,於是 SSG/ISR/SSR 把渲染搬回伺服器;SSR 又製造出 hydration 的延遲,於是 React Server Components 只送需要互動的那部分。
同一時間另一條線在跑:客戶端變多,後端被 BFF 切開;SPA 本身變大,於是切成模組化單體;團隊再變大,才切成 micro-frontend。他用同一張六軸卡片(擴展性、效能、複雜度、團隊規模、產品價值、成本)替每一站評分,讓「架構沒有好壞、只有取捨」變成看得見的東西——而且他一再往回踩煞車:clean architecture 在前端多半是過度設計、Next.js 不要過早搬、小公司做 micro-frontend 是自找麻煩。最後他把整條鏈收成一個可執行的動作:稽核自己的 code base,寫下你在哪一站、為什麼在這裡、下一步是哪裡,並把面試回答從「我們用 React」升級成一句同時包含渲染策略、repo 結構與未來方向的話。
推理鏈:每段留給下一段的線索
每一列是一段,箭頭後的字是這段留給下一段的線索。點段落標題跳到該段。
- 開場:面試考的是架構取捨 → 既然架構是被問題推著走的,那就得先問:最早的網頁是什麼樣子,是什麼問題把它推向下一站?
- 從靜態頁面到 MVC → MVC 解決了動態內容,但整頁重載的體驗還是很差。下一個問題是:能不能不重載就更新畫面?
- SPA:邏輯搬到瀏覽器那一刻 → 邏輯從伺服器搬到瀏覽器,是一次程度上的移動而不是非黑即白。在往下走之前,需要一把尺來量這個程度。
- thick client 與 thin client → 到目前為止都只有一個 client。但當手機、平板、多種裝置同時來要資料時,後端那一側會發生什麼事?
- BFF 與 GraphQL:後端被切開 → 後端那一側的分裂解決了,但前端最初的痛點還在原地:SPA 仍然送出太多 JavaScript,使用者仍然盯著空白畫面。
- SSG 與 ISR:回到伺服器產頁面 → SSG 與 ISR 解決了速度與 SEO,但它們的前提是頁面對所有人都一樣。那需要個人化、需要真互動的頁面怎麼辦?
- SSR、hydration 與 React Server Components → 這一整條渲染演化把效能推到極致,但每一步都在加東西。那總帳算下來,代價是什麼?
- 渲染策略的代價與過早遷移的警告 → 渲染這條線走到底了,但 SPA 內部本身從頭到尾沒有變過。當它自己大到難以維護時,該怎麼辦?
- 模組化前端單體:先畫出邊界 → 邊界要怎麼畫才對?這時候很自然會想去借經典軟體架構的成熟答案。
- clean architecture 在前端值不值得 → 如果邊界光靠紀律守不住,那還有一種更硬的辦法——把邊界變成部署的邊界。
- micro-frontend:企業級的最後一站 → 六站走完了,但知道有哪些架構跟能在面試裡講清楚自己的架構是兩回事。最後需要一個把這些變成自己的東西的動作。
- 架構稽核與資深的回答長什麼樣
3. 逐段說明
Every Frontend Architecture Pattern Explained in 23 Minutes
1. 開場:面試考的是架構取捨 0:00–0:43
作者開門見山:資深前端面試考的不是寫程式,而是架構取捨。monolith 與 micro-frontend 差在哪、clean 還是 hexagonal、SSR 還是 SSG——答不出來就只會被歸類成中階。這支影片要走一遍前端架構的演化:靜態頁面 → MVC → SPA → BFF → 模組化單體 → micro-frontend,每一站講取捨與適用時機,最後給一份可以照著做的架構稽核清單。
推理作者一開口就把評分標準換掉:資深前端面試考的不是寫程式,是架構取捨。他用四個具體的對比題證明這件事——monolith 對 micro-frontend、clean 對 hexagonal、SSR 對 SSG——並直接說出後果:答不出來,你聽起來最多就是中階。有了這個標準,整支影片的形式才成立:不是列出所有架構,而是走一遍它們為什麼依序出現,每一站都問取捨與適用時機,最後給一份可以照著跑的稽核清單。
AI 補充作者沒有明說的是,為什麼「取捨」會成為資深的判準。原因是架構決策幾乎沒有正確答案,只有在特定條件下比較不痛的答案。一個只會說「我們用 Next.js」的人,面試官無法判斷他是想清楚才選的、還是跟著範本走;而一個能說出「我們為了 SEO 選 SSG,代價是內容更新要重新 build,所以我們用 ISR 補上」的人,等於當場展示了他做決策的方式。另外值得先建立的心理準備是:這支影片講的順序是**歷史順序**,不是好壞順序。後面出現的架構並不「比較好」,它們只是解決了更後面才出現的問題,同時付出更高的複雜度。
2. 從靜態頁面到 MVC 0:43–2:22
起點是純 HTML/CSS 加一點 JavaScript:快,但零互動,像一本雜誌。第一個架構風格 MVC 因此登場——Django、Rails、.NET 都是這樣開始的:view 還是靜態 HTML,但由跑在伺服器上的 model 與 controller 把資料與模板混出客製化的頁面。代價是每換一頁就整頁重載、效能與擴展性都差,前後端緊密耦合,而且框架鎖定嚴重,換框架幾乎等於重寫。好處是複雜度低、能做的邏輯比純靜態頁多。


推理起點是純 HTML 與 CSS 加一點點 JavaScript:極快,但零互動,作者形容它像雜誌或報紙,只有文字和圖片。這個「零互動」就是推動下一站的力量,於是 MVC 出現——Django、Rails、ASP.NET 都是這樣起家的。它的作法是:view 仍然是產出的 HTML,但由跑在伺服器上的 model 與 controller 用 PHP、Python 或 Java 把資料與模板混合,吐出客製化的頁面。作者接著用六軸卡片替它評分:擴展性最低、效能不佳、複雜度低、團隊規模小,適合 CRUD 應用、小團隊與快速原型。代價是每換一頁就整頁重載、前後端緊密耦合,還有嚴重的框架鎖定——從一個框架換到另一個幾乎不可能。
- CMVC:model 與 controller 在伺服器把資料混進模板吐出 HTML,互動要整頁重載→ 畫地圖
- EMVC 六軸:擴展性最低、效能不佳、複雜度低、團隊小;適合 CRUD、小團隊、原型→ 存+演練
- A「渲染發生在哪裡,決定了誰快、誰慢、誰耦合」是解釋整條演化的同一把鑰匙→ 批判類比
AI 補充這裡有一個值得補上的細節:MVC 的「view 在伺服器」是它所有優缺點的共同來源。因為畫面是伺服器組出來的,所以 SEO 天生就好、首屏天生就快、也不需要前端工程師;但也因為畫面是伺服器組出來的,任何互動都得回伺服器要一份新的 HTML,於是整頁重載無法避免。理解這一點,後面每一次「把渲染搬來搬去」的演化就都能被同一句話解釋:**渲染發生在哪裡,決定了誰快、誰慢、誰耦合**。另外要注意作者說的「框架鎖定」在今天仍然成立,而且是 MVC 這一站被淘汰的真正原因之一——樣板語法、ORM、路由全部綁在一起,換框架等於重寫。
3. SPA:邏輯搬到瀏覽器那一刻 2:22–4:07
JavaScript 起飛後進入單頁應用時代:前端用 React、Vue 或 Angular 寫,後端退化成提供資料的 API,驗證、授權與狀態管理都搬到瀏覽器。換來的是不重載就能更新畫面的互動性、更好的擴展性與效能。作者點出一個關鍵的副作用:SPA 誕生的那一刻,「前端工程師」這個職位才誕生,因為邏輯被搬過來了,團隊可以更大、產品可以更複雜。代價是 JavaScript 太多、首次載入很慢,而且初始畫面是空的,SEO 很差。


推理作者把 SPA 描述成一次重心轉移:畫面用 React、Vue 或 Angular 在瀏覽器裡建,後端退化成提供資料的 API——他特別說「那個 API 就是我們以前的 view,但現在它只是個 model」。驗證、授權與狀態管理跟著搬到前端,於是不重載就能更新畫面。他接著點出這件事最重要的社會學後果:**SPA 誕生的那一刻,前端工程師這個職位才誕生**,因為邏輯被搬過來了,團隊可以更大、產品可以更複雜,儀表板與 SaaS 這類產品才成為可能。六軸上 SPA 幾乎每一項都比 MVC 高,但代價寫在最後:送出太多 JavaScript、首次載入很慢,而且初始畫面是空的,SEO 很差。
- CSPA:畫面在瀏覽器建,後端退化成資料 API;前端工程師這個職位從此誕生→ 畫地圖
- E搬走的不只渲染,還有狀態所有權:瀏覽器養一份資料副本,快取/失效/樂觀更新變前端日常→ 存+演練
- R「SPA SEO 很差」今天要打折:搜尋引擎會跑 JS,但有延遲;社群預覽爬蟲多半不跑 JS→ 存+回想
AI 補充「後端退化成 model」這個說法很傳神,但要補上它省略的一步:搬走的不只是渲染,還有**狀態的所有權**。伺服器渲染時,畫面就是資料當下的樣子,沒有「同步」這個問題;SPA 則在瀏覽器裡養了一份資料副本,於是快取、失效、樂觀更新、race condition 全部成為前端的日常工作——這也是為什麼後來會冒出那麼多狀態管理工具。至於 SEO 這一點,今天要打點折扣:主流搜尋引擎已經會執行 JavaScript 再索引,純 SPA 不再等於搜不到;但執行有排程延遲、非搜尋引擎的爬蟲(社群分享的預覽卡片)多半不跑 JavaScript,所以「內容型網站別用純 CSR」的結論仍然成立,只是理由從「搜不到」變成「慢且不可靠」。
術語:client-side routing
「And because you get this initial empty page, you also have very poor SEO.」
4. thick client 與 thin client 4:07–5:05
在往下走之前,作者插入一個貫穿全片的座標軸:thin client 把大部分邏輯交給後端,像靜態頁面;thick client 自己扛大量商業邏輯,把後端當成儲存空間。從 thin 走到 thick,就是不斷把邏輯往前端搬的過程。他刻意不展開優劣,只要求你記住這個軸,並且問自己:你的 client 應該厚到什麼程度?

推理他刻意打斷演化敘事,先建立一個座標軸:thin client 把大部分邏輯交給後端,典型就是靜態頁面;thick client(或 fat client)自己扛大量商業邏輯,把後端更多地當成儲存空間用。從 thin 走到 thick,就是不斷把邏輯往前端搬的過程——也就是前面兩段發生的事。他明講不展開優劣,只要求你記住這條軸,並且問自己:你的 client 應該厚到什麼程度?
- Rthin ↔ thick client 是一條軸:邏輯往前端搬越多越 thick,後端越像儲存空間→ 存+回想
- Rclient 越厚的三個代價:邏輯不可信任、版本管理痛、但同一應用可逐畫面選厚度→ 存+回想
AI 補充作者把這條軸留白了,但它其實有幾個很實用的判準,值得補上。第一,**邏輯放在 client 的那一刻就不可信任**:任何驗證、價格計算、權限判斷,前端做的版本只能算體驗優化,後端一定要再做一次,否則就是漏洞。第二,**client 越厚,版本管理越痛**:使用者的瀏覽器裡跑的可能是三週前的舊版,而 thin client 每次進來拿到的都是最新的。第三,這條軸不是全有全無的,同一個應用可以在不同畫面上選不同厚度——這正是後面 React Server Components 在做的事:讓元件樹的一部分是 thin、一部分是 thick。
5. BFF 與 GraphQL:後端被切開 5:05–7:53
行動裝置出現後,多種 client 打同一支 API,於是 BFF(backend for frontend)出現:每個前端應用配一個專屬後端,因為手機的畫面需要的是同一批資料的不同形狀,硬塞進單一 API 會變成科學怪人。作者強調這對前端的意義——BFF 通常由前端團隊自己擁有,於是前端工程師被推向全端。GraphQL 則解決 REST 的 overfetching 與 underfetching,但帶來 N+1 問題與圖思維的複雜度。結構上的收穫是:BFF 後面可以接很多微服務,後端團隊各自每天出貨,前端不被打斷,團隊因此可以長大。代價是耦合、單點故障、多一次網路往返,以及可觀的前期學習成本。


推理作者的推理很直接:手機和桌機的畫面完全不同,可能要同一批資料但要的是不同形狀;硬塞進單一 API 會變成科學怪人,所以應該每個前端配一個專屬後端——這就是 BFF。接著他點出這對前端的意義:BFF 多半由前端團隊自己擁有,於是前端工程師被推向全端。GraphQL 則被放在同一條線上,因為它解決的是同一類問題的另一半——REST 的 overfetching 與 underfetching;但它也帶來 N+1 問題與用圖思考的複雜度。結構上真正的收穫在人:BFF 後面可以接一整排微服務,後端團隊各自每天出貨,前端團隊不被打斷,於是團隊規模可以長大。六軸上 BFF 幾乎全面高於 SPA,但他同時列出三個缺點——緊密耦合、擴展性上限、單點故障,而且多了一次網路往返、前期學習成本很高。
- CBFF:每種前端各配一個專屬後端,把下游資料整成該畫面要的形狀,通常由前端團隊擁有→ 畫地圖
- RGraphQL:client 在查詢裡指定要哪些欄位,解 REST 的 over/underfetching,但帶來 N+1→ 存+回想
- ABFF 與 GraphQL 常被混講,其實一個是「誰擁有 API 層」的組織決策,一個是「查詢長什麼樣」的技術決策→ 批判類比
- RN+1 是 GraphQL 每個欄位各自解析造成的;標準解法是 DataLoader 批次合併→ 存+回想
AI 補充這裡有一個需要澄清的觀念:**BFF 與 GraphQL 是兩個獨立的決定,經常被混在一起講**。BFF 是「誰擁有這層 API」的組織決策,你完全可以用 REST 寫 BFF;GraphQL 是「查詢語言長什麼樣」的技術決策,也可以直接暴露給 client 而沒有 BFF。作者把它們並排是因為它們常一起出現,但面試時分開講會顯得更清楚。另外「BFF 由前端團隊擁有」這句話的重量常被低估:它意味著前端團隊要接下部署、監控、on-call 與資安責任,這是真正的成本所在,比學 GraphQL 語法貴得多。至於 N+1 問題,它其實是 GraphQL 的架構特性——每個欄位各自解析,所以一個回傳一百筆的清單查詢,底下的關聯欄位就會觸發一百次呼叫;標準解法是 DataLoader 這類把同一輪的請求批次合併的機制。
術語:N+1 problem
6. SSG 與 ISR:回到伺服器產頁面 7:53–9:43
後端問題解決了,前端仍然送出太多 JavaScript、使用者盯著空白畫面。於是 SSG、ISR、SSR 與 Next.js、Nuxt 這類 meta framework 登場。SSG 是「回到未來」:仍然用現代框架開發,但最後產出靜態頁面丟到 CDN,快到極點又便宜;代價是幾乎沒有互動性,內容要改就得重新 build、重新部署。ISR 是它的進化——依 TTL 在請求進來時判斷是否過期,過期就回資料源重新產生並替換 CDN 上的快取,內容因此能動態更新,但仍然撐不起真正的互動。


推理作者的解法是把渲染搬回伺服器,而且他自己形容這是「回到未來」——回到最初那個靜態網頁的形態,只是這次帶著現代工具。SSG 的作法是:開發時仍然用 React 或 Vue,但 build 時就把頁面產成靜態檔案丟到 CDN,於是快到極點又便宜。代價很明確:幾乎沒有互動性,而且內容要改就得重新 build、重新部署。ISR 是針對這個代價的直接修補——給頁面一個 TTL,請求進來時若已經過期,就回資料源重新產生、替換 CDN 上的快取。這讓內容能動態更新,但作者馬上踩住:它仍然撐不起真正的互動。
- CSSG:build 時把頁面產成靜態檔丟 CDN,極快極便宜;但零互動、內容改了要重 build→ 畫地圖
- CISR:靜態頁帶 TTL,過期後由請求觸發重新產生並換掉 CDN 快取;仍撐不起真互動→ 畫地圖
- EISR 通常「先給舊的、背景更新」,踩到過期的人拿到的仍是舊頁,下一位才看到新的→ 存+演練
- RSSG 與 ISR 的共同前提:頁面對所有人都一樣;一出現「你好,某某」快取就沒法共用→ 存+回想
AI 補充投影片上的流程圖比口述精確,值得把差別講清楚。SSG 的產生時機是 **build 時**,所以頁面數量會直接變成 build 時間,一萬篇文章就是一萬次渲染;ISR 則把產生時機移到 **第一個過期後的請求**,build 因此變快,代價是有人會踩到那次重新產生。實務上還有一個作者沒提的重點:ISR 通常是「先給舊的、背景更新」,也就是踩到過期的那位使用者拿到的仍然是舊頁面,新的那份要下一位才看得到——這解釋了為什麼「我改了資料庫但頁面沒變」是 ISR 最常見的困惑。另外要注意,這一整套的前提是**內容不因人而異**。一旦頁面要顯示「你好,某某某」,快取就沒辦法共用,SSG 與 ISR 都失去意義,這正是下一站必須存在的原因。
7. SSR、hydration 與 React Server Components 9:43–12:05
SSR 把同一套 JavaScript 框架搬到伺服器跑,先產出帶有初始狀態的 HTML 送給瀏覽器,使用者不再面對空白頁。但要讓那頁真的能互動,還得下載 bundle、跑起框架、建出 virtual DOM,再把它接到已經存在的 HTML 上——這就是 hydration。結果是「看得到很快、能點還是很慢」,中間那段時間使用者按了按鈕沒反應。演化的最後一站是 React Server Components:把元件樹上沒有互動的部分留在伺服器,只把真正需要互動的那部分送到瀏覽器,送出的 JavaScript 大幅減少,可互動的時間點也提前。作者順帶提到同一哲學下的 island architecture,但認為能講清楚 RSC 就夠用了。



推理SSR 的作法是把同一套框架搬到伺服器跑,先產出帶有初始狀態的 HTML 送給瀏覽器,使用者不再面對空白頁。但作者立刻指出故事沒完:要讓那頁真的能點,還得下載 bundle、執行框架、建出 virtual DOM,再把它接到已經存在的 HTML 上——這就是 hydration。投影片上的時間軸把代價畫得很清楚:先是渲染伺服器產生的 HTML、達到首次內容繪製,接著才下載與執行 JavaScript,最後才 hydrate、才真的可互動。結果就是「看得到很快、能點還是很慢」,中間那段時間使用者按了按鈕不會有反應。演化的最後一站因此是 React Server Components:把元件樹上沒有互動的部分留在伺服器,只送真正需要互動的那個子集到瀏覽器——投影片上兩棵樹的對比正是這件事,伺服器那棵完整,客戶端那棵小很多。送出的 JavaScript 少了,可互動的時間點自然提前。他順帶提到同一哲學的 island architecture,但認為能講清楚 RSC 就夠用了。
- CSSR:每次請求在伺服器跑前端框架、產帶初始狀態的 HTML;看得到很快,能點還要等 hydration→ 畫地圖
- Chydration:瀏覽器重跑一次元件邏輯,把事件與狀態接回伺服器送來的死 HTML→ 畫地圖
- ESSR 時間軸:伺服器 HTML → 首次內容繪製 → 下載執行 JS → hydrate → 才能點;中間按了沒反應→ 存+演練
- CRSC:沒互動的元件留在伺服器,只送需要互動的子集到瀏覽器;JS 少了,可互動時間提前→ 畫地圖
- RSSR/RSC 兩個實務痛點:hydration mismatch(時間/隨機/window)與 use client 邊界只能傳可序列化資料→ 存+回想
AI 補充這一段的因果鏈可以再收緊一句:**hydration 是為了修補「HTML 沒有帶著行為」這個先天缺陷而存在的**。伺服器送過來的是死的字串,事件監聽器、狀態、元件對應關係全都不在裡面,所以客戶端必須重跑一次同樣的渲染,才能把行為對回去——這就是為什麼那份 JavaScript 躲不掉,也是為什麼 RSC 的思路是「一開始就別讓那些元件進入客戶端的樹」。另外有兩個實務上很痛、作者沒提的點。第一是 **hydration mismatch**:伺服器與客戶端渲染出的結果必須一致,任何依賴時間、隨機值或 window 的程式碼都會讓兩邊對不上,React 會警告甚至整段重畫。第二是 RSC 的真正代價不在效能而在心智模型:同一個檔案裡有些程式碼在伺服器跑、有些在瀏覽器跑,邊界由 `use client` 這類指示決定,跨界只能傳可序列化的資料——投影片自己也把這點寫成「更快的互動,但更高的心智模型複雜度」。
8. 渲染策略的代價與過早遷移的警告 12:05–13:23
作者為這一整條渲染演化算總帳:這是目前已知效能最好的建構方式,SEO 好、載入快,但擴展性反而比純客戶端渲染差——純靜態資產丟 CDN 極易擴展,一旦有伺服器端的預渲染工作,基礎設施就更複雜也更貴。複雜度極高、新人難上手、對框架的意見高度依賴,版本一改就得跟著調整。他因此給出明確的警告:只有在效能真的是產品瓶頸時才走這條路(例如電商),他知道不少公司過早搬到 Next.js,現在正在往回退。

推理作者的結論是:這是目前已知效能最好的建構方式,SEO 好、載入快。但接著他做了一個違反直覺、也最有價值的判斷——擴展性反而比純客戶端渲染**差**。理由很乾淨:純靜態資產丟 CDN 極易擴展,一旦有伺服器端的預渲染工作,就需要更複雜也更貴的基礎設施。複雜度他直接評成極高:技術越多,要懂的越多,新人越難上手,而且對框架的意見高度依賴,版本一改就得跟著調整。所以他的建議是條件式的:只有在效能真的是產品瓶頸時才走這條路,例如電商。他還加了一句很有份量的觀察——他知道不少公司過早搬到 Next.js,現在正在往回退。
AI 補充「效能最好但擴展性最差」這個看似矛盾的判斷,關鍵在於這兩個詞量的不是同一件事。**效能**量的是單一使用者感受到的速度,**擴展性**量的是流量成長時成本與複雜度的增加曲線。靜態檔案的曲線幾乎是水平的;每個請求都要跑一次 React 的伺服器,曲線就是斜的。理解這個區分,後面每一張六軸卡片才讀得懂。至於「過早遷移」這個現象,值得補上它的成本結構:搬到 SSR 之後,你多了一個必須維運的 Node 執行環境、一組新的錯誤類型(伺服器與客戶端狀態不一致、只在伺服器端爆掉的第三方套件)、以及一份跟框架版本綁死的部署方式。這些成本在 demo 階段完全看不到,卻會持續支付。判斷是否該搬的問法應該是:目前的載入速度真的在傷害轉換率或搜尋排名嗎?有數據嗎?
9. 模組化前端單體:先畫出邊界 13:23–14:28
前面談的都是讓 SPA 變快,但 SPA 內部本身沒有變。當它大到某個程度——作者舉的例子是三百個開發者貢獻同一份 code base——維持品質與持續出貨就變得極難。做法是在模組之間加上邊界:把共用 UI 與邏輯(design system、全域 CSS、可重用 hook)與共用服務(資料抓取、logging、analytics)抽出來,交給平台團隊維護;實際做功能的人則分進領域團隊,user 歸 user、payments 歸 payments,資料夾結構也跟著這樣切。

推理作者先給規模感:他做過三百個開發者貢獻同一份 code base 的專案,在那個尺度下維持品質、又不讓人互相弄壞東西,極其困難。解法是在模組之間加上邊界,而他切的方式是兩層。橫的一層是共用:共用 UI 與邏輯(design system、全域 CSS、hooks、驗證)與共用服務(auth、資料抓取、logging、analytics),由平台團隊擁有與維護。直的一層是領域:user 歸 user、payments 歸 payments、billing 歸 billing,做功能的人分在領域團隊裡,資料夾結構也照著這樣切。他形容這是在大型單體裡「很快地放進一些秩序」的方法。
AI 補充這個切法之所以有效,是因為它同時解決了技術與組織兩個問題,而作者只講了技術那一半。組織那一半是:平台團隊與領域團隊的分工,其實是把「誰有權改什麼」寫進了目錄結構。共用層改動的爆炸半徑是全公司,所以需要一組專責的人與更嚴格的流程;領域內的改動只影響自己,可以放手做。這也意味著平台團隊的產出必須被當成產品來經營——有版本、有文件、有淘汰策略,否則它會退化成「沒人敢動的那個資料夾」。另外要提醒一個常見誤解:畫在圖上的邊界和程式碼裡真正的邊界是兩回事,作者稍後自己也會承認這一點。
術語:modular monolithdomain-driven design
10. clean architecture 在前端值不值得 14:28–17:55
要實作模組邊界,可以借經典軟體架構的想法,最常見的是 clean architecture。作者用 React 舉例:把最通用的實體(user、product)抽成 domain,往外是 use case 與 repository,最外層才是 framework 與 infrastructure,所以理論上可以把 React 元件換成 Vue 或 Angular 而不動其他程式碼。但他接著自問自答:前端真的用得上嗎?短答是「有時候」。因為前端框架本身就很有意見、自帶結構,前端通常比較薄,也不像後端有那麼多邏輯;而「可以換框架」這個好處,在多數專案的生命週期裡根本用不到,投資那些抽象往往就是過度設計。他的界線是:只有非常大、或確定會活十五年的專案才值得。hexagonal 與 onion architecture 同理——概念是同一個洋蔥,最穩定的商業領域在中心,但重心都在後端。實務上跟著 Next.js 這類框架的意見走,九成九的情況就夠了。回到單體本身:擴展性跟 SPA 一樣、團隊可以更大,但代價是全域狀態、極長的 build 時間,以及最難的一點——邊界很容易畫,卻很難真的被遵守。



推理作者先老實示範這條路怎麼走:clean architecture 的想法是把最通用的實體(user、product)抽成 domain,往外是 use case 與 repository,最外層才是 framework 與 infrastructure,依賴永遠由外往內。投影片上的 React 範例把這四層寫在同一個檔案裡,箭頭一路往上指向 domain,而最漂亮的地方是——最下面那段 React 元件可以整段換成 Vue 或 Angular,其他程式碼一行都不用動。但他接著自問自答,而且答得很不客氣:前端真的用得上嗎?短答是「有時候」。投影片直接列出四個理由:前端框架本身就很有意見、自帶結構;前端通常是薄的,加更多結構只是額外負擔;只有在真的要換框架、需要穩定的商業邏輯時才有用;而它最大的價值其實是幫你思考怎麼解耦。他的界線因此很具體:只有非常大、或確定會活十五年的專案才值得投資這些抽象,否則就是過度設計。hexagonal 與 onion architecture 同理——本質上都是同一顆洋蔥,最穩定的商業領域在中心,但重心都在後端。實務上跟著 Next.js 這類框架的意見走,九成九的情況就夠了。最後他回到單體本身算帳:擴展性跟 SPA 相當、團隊可以更大,但代價是全域狀態、極長的 build 時間,以及最難的一點——邊界很容易畫在圖上,卻很難真的被遵守,實際上相依會長得到處都是。
- Rclean architecture:同心圓、依賴只能由外向內;前端多半用不上,值得留的是依賴方向這條規則→ 存+回想
- A「可以整段換掉 React」這個賣點在前端要打折:框架相關程式碼本身就是八成→ 批判類比
- R前端用不上 clean architecture 的四個理由(投影片)→ 存+回想
- R模組化單體的三個代價:全域狀態、極長 build 時間、邊界畫在圖上卻難遵守→ 存+回想
AI 補充「可以整段換掉 React」這個賣點需要用力打折,因為它是這類架構最常被高估的地方。在後端,UI 只是眾多入口之一,抽掉框架後核心邏輯仍然佔大部分程式碼;但在前端,**框架相關的程式碼本身就是絕大多數**——元件結構、狀態管理、表單、路由、動畫、無障礙處理,這些全都在最外層。所以就算你完美遵守分層,換框架時要重寫的仍然是八成的程式碼,被保住的那份純邏輯往往只是幾個計算函式。這也是為什麼作者說它更像「心智練習」而不是投資。真正值得從中保留的是那條依賴方向的規則:**讓不穩定的東西依賴穩定的東西,不要反過來**。這條規則不需要整套分層就能實踐——例如不要讓資料抓取的細節滲進元件、不要讓 API 的回應形狀直接當成畫面的狀態形狀。至於他最後那句「邊界很難被遵守」,其實有工程解法可以補:用 lint 規則或 build 設定把跨領域的匯入直接擋掉,讓違規在 CI 就失敗,而不是靠自律。
術語:hexagonal architecturerepository patterndependency inversion
「So basically you have an application where you could entirely swap your front-end framework and you wouldn't have to change the whole thing.」
11. micro-frontend:企業級的最後一站 17:55–20:30
最後是 micro-frontend:把上一段畫出來的領域真的拆成獨立部署的應用,在執行時再組起來。header、footer、使用者區塊各自是獨立前端應用,一個 shell 元件負責把它們拼起來並注入共用 CSS 與共用狀態。畫面因此可以按團隊切成垂直切片,每個團隊擁有自己那一塊的前後端、各自獨立部署、全部平行進行。作者給了很硬的判準:公司有上千名工程師在同一個 client 應用上工作時才需要它;小公司走這條路是自己搬石頭砸腳,只會更慢。技術上可以用 Webpack module federation,但把多個應用在使用者落地時組起來,效能一定會有折損。他也提醒:不少小公司因為 FOMO 還是會在面試裡問,所以至少要能說清楚什麼時候該用、高層次上怎麼運作。



推理作者把 micro-frontend 描述成「單頁應用遇上企業軟體」:上一段畫出來的領域被真的拆成獨立部署的應用,在使用者載入頁面時才組合起來。投影片上的結構跟模組化單體那張幾乎一樣,差別只在最外層從一個 monolith 邊框換成一個 shell——shell 持有共用 CSS 與共用狀態,再注入到各個獨立應用裡。他接著用一個電商頁面示範這在畫面上長什麼樣:商品區、購物車、推薦區分屬三個團隊,每個團隊擁有自己那一塊的前後端,各自獨立部署、全部平行進行。然後是全片最硬的判準:公司有上千名工程師在同一個 client 應用上工作時才需要它;小公司走這條路是自己搬石頭砸腳,只會更慢。六軸上它的擴展性、團隊規模、產品價值都接近滿格,但效能明顯掉下來——因為所有應用要在使用者落地時才被組起來——而複雜度與成本同樣接近滿格。技術上可以用 Webpack module federation。最後他提醒:不少小公司因為 FOMO 也會在面試裡問,所以至少要能說清楚什麼時候該用、高層次上怎麼運作。
- Cmicro-frontend:領域真的拆成獨立部署的應用,shell 在使用者落地時把它們組起來→ 畫地圖
- E門檻:上千名工程師在同一個 client 上工作才需要;小公司走這條路是自己搬石頭砸腳→ 存+演練
- R共用得越多,獨立性越假:活得下來的 micro-frontend 只共用設計代幣與少數版本化元件→ 存+回想
AI 補充作者說 shell 會注入共用 CSS 與共用狀態,但沒有點出這裡藏著整個模式最大的矛盾:**共用得越多,獨立性越假**。共用狀態意味著各團隊被同一份契約綁住,改它就要協調所有人;共用 CSS 更危險,因為樣式沒有天然的隔離,一個團隊改了全域樣式可能弄壞別人的畫面。真正在生產環境活得下來的 micro-frontend,通常對共用的東西極度吝嗇:只共用設計代幣與少數版本化的元件,其餘一律各自複製一份,寧可重複也不要耦合。另外「效能會下降」值得說得更具體:每個獨立應用可能各自帶一份 React,於是同一個框架被下載好幾次;module federation 的作用正是讓它們在執行時共用同一份實例,但這要求各團隊的版本必須相容——而版本協調恰恰是這個模式想要消滅的東西。這個張力沒有乾淨的解法,只有取捨,這也正好呼應整支影片的主題。
術語:shell application
12. 架構稽核與資深的回答長什麼樣 20:30–22:33
收尾是一份可以直接照做的架構稽核:坐下來研究自己現在的 code base,回答三個問題——目前是什麼架構風格?為什麼會走到這裡?下一個自然的步驟是什麼?把你正在用的模式全部寫下來,對照影片那張演化全圖。接著是回報方式的升級:面試被問到手上的專案時,不要停在「我們就是用 React 跟 Next.js」,而要說成「靜態頁面走 SSG,個人化的部分用 SSR,repo 結構是模組化單體,隨著規模成長我們有評估過未來走 micro-frontend」。他把答不出這種話的後果命名為 back-end rejection:面試當下一切都好,幾天後收到一封「我們找到更有經驗的人」的罐頭信——不是你做錯了什麼,而是你沒有做夠對的事。


推理作者把整支影片收成一份可以立刻執行的稽核:坐下來研究自己現在的 code base,回答投影片上那幾個問題——目前是什麼架構風格?為什麼會走到這裡?自然的下一步是什麼?還用到了哪些其他模式,BFF?MVC?SSR?全部寫下來,對照影片走過的這一整排。接著是回報方式的升級,他直接給出前後對照:從「對啊,我們就是用 React 跟 Next.js」,變成「我們透過 SSG 提供靜態頁面,用 SSR 處理個人化,repo 結構做成模組化單體,隨著規模成長我們也評估過未來走向 micro-frontend」。最後他替失敗的情況取了名字——back-end rejection:面試當下一切都好,幾天後收到一封「我們找到更有經驗的人」的罐頭信。他的判斷是:那不是因為你做錯了什麼,而是因為你沒有做夠對的事。
- P架構稽核:對自己的 code base 回答「現在是什麼、為什麼走到這、下一步是什麼、還用了哪些模式」→ 練習
- Rback-end rejection:面試當下都好,幾天後收到「找到更有經驗的人」的罐頭信→ 存+回想
AI 補充那句範例回答之所以有效,值得拆開來看,因為它可以直接被套用:它在一句話裡回答了三個不同層次的問題——**渲染策略**(SSG 加 SSR)、**程式碼組織**(模組化單體)、**演化方向**(考慮過 micro-frontend)。這正好對應這支影片的兩條主線加上一個時間維度,也正好是面試官想確認的三件事:你知道你在哪、你知道為什麼在這、你知道下一步。要讓這句話真的可信,還缺一樣東西作者沒提:**理由**。更強的版本會補上取捨,例如「用 SSG 是因為商品頁要 SEO,個人化的部分才用 SSR,因為我們不想放棄 CDN 快取」。有了理由,這句話才從背下來的清單變成你自己的決策。至於 back-end rejection 這個命名,它其實描述的是一個更普遍的現象:面試的淘汰理由通常不會被告知,所以你不會從結果學到任何東西——這也正是為什麼要事先把自己的架構故事準備好,而不是等被拒絕後才猜原因。
4. 總結
整支影片的主張是:架構沒有好壞,只有在特定條件下比較不痛的選擇,而資深與否就看你能不能把這些條件說出來。它用一條因果鏈把所有架構串起來——每一站都是為了解決上一站的痛點而生,而每個解法又製造出下一站的問題。靜態頁面快但零互動,於是 MVC 把邏輯搬上伺服器;MVC 整頁重載又前後端緊耦合,於是 SPA 把邏輯搬進瀏覽器,也順便創造了「前端工程師」這個職位;SPA 送出太多 JavaScript、首屏空白,於是 SSG 與 ISR 把渲染搬回 build 時,但它們的前提是頁面對所有人一樣,需要個人化就得靠 SSR;SSR 又製造出 hydration 的空窗——看得到卻點不動——於是 React Server Components 只把需要互動的那部分送到瀏覽器。同一時間另一條線在跑:客戶端變多,後端被 BFF 切開,前端工程師被推向全端;SPA 自己變大,切成模組化單體,由平台團隊守共用層、領域團隊做功能;團隊再變大,邊界靠紀律守不住,才升級成部署邊界,也就是 micro-frontend。作者一路往回踩煞車:clean architecture 在前端多半是過度設計,因為前端最大宗的程式碼本來就住在最外層;Next.js 不要在效能還不是瓶頸時就搬;小公司做 micro-frontend 只會更慢。最後他把整條鏈折成一個可執行的動作——稽核自己的 code base,寫下你在哪一站、為什麼在這、下一步是哪裡,並把面試回答從「我們用 React」升級成一句同時涵蓋渲染策略、repo 結構與演化方向的話。
勘誤總整理
確定錯誤/已過時見仁見智(取決於版本或情境)
| 段落 | 原話(transcript 逐字) | 說明 |
|---|---|---|
| 3. SPA:邏輯搬到瀏覽器那一刻 4:18 |
「And because you get this initial empty page, you also have very poor SEO.」 | 在今天要打折扣。Google 等主流搜尋引擎已經會執行 JavaScript 後再索引,純 SPA 不等於搜不到。但執行有排程延遲、內容更新反映得慢,而且社群平台產生分享預覽時多半只讀初始 HTML 的 meta 標籤、完全不跑 JavaScript。所以結論仍然成立,理由要改成「慢且不可靠」,而不是「搜不到」。 依據: Google Search Central 文件說明 JavaScript 網站的兩階段索引(crawl → render queue → index) |
| 10. clean architecture 在前端值不值得 15:33 |
「So basically you have an application where you could entirely swap your front-end framework and you wouldn't have to change the whole thing.」 | 在前端要大打折扣。後端抽掉框架後核心邏輯仍佔大部分程式碼,但前端最大宗的程式碼——元件結構、狀態管理、表單、路由、動畫、無障礙處理——本來就住在最外層。即使完美分層,換框架仍要重寫絕大部分,被保住的往往只是幾個純計算函式。作者自己在幾句話後也承認這通常是過度設計。 依據: 同段稍後他自己的結論:「investing in those abstractions to make that possible it's usually just overengineering」 |
5. 推薦三個下一步
1. 往下挖深:micro-frontend 的實際組裝方式
影片承認只講到高層次,但真正的難處全在細節——共用相依怎麼避免被下載五次、跨應用的狀態與路由怎麼設計、樣式怎麼隔離。作者自己也說他可以另外做一支,這個缺口值得自己補上。
YouTube 搜尋:Webpack module federation micro frontend tutorial micro frontend shared state routing patterns single-spa vs module federation
2. 往旁邊對照:質疑 SPA 與重新回到伺服器的聲音
影片把演化講成一條單向前進的線,但實務上有一整派人主張多數網站根本不需要 SPA。聽過 HTMX、Astro 這類「少一點 JavaScript」的論述,才能判斷你的專案是不是被預設值推著走。
YouTube 搜尋:HTMX vs React when you don't need a SPA islands architecture Astro explained the cost of hydration resumability Qwik
3. 往上應用:實際做一次架構稽核並量化現況
影片最後那份稽核只有三個問題,但要回答「下一步是什麼」需要數據支撐——目前的 bundle 有多大、載入指標落在哪、build 要跑多久。把這些量出來,稽核才會從自述變成論證。
YouTube 搜尋:bundle analyzer webpack vite tutorial Core Web Vitals LCP INP measure real users architecture decision record ADR frontend
- 接著看 ←Top 15 Frontend Interview Questions for 2026 (wa/ Senior Engineer) · 面試題只點到 monolith 與 micro-frontend,這站把整條架構演化與六軸取捨攤開
- 接著看 →3 Frontend Skills AI Can't Replace (become AI-proof) · 模組邊界從架構圖變成實際判準:邊界清楚,agent 改一次才省 token
- 接著看 →Real Senior Frontend System Design Interview 2026 (AI Coding Included) · SSR、SSG、BFF、CDN 在架構演化站被系統性建立,這站直接當成選項拿來取捨
- 接著看 →Frontend System Design Explained w/ Senior Engineer (Microfrontends, Monorepo, MCP UI, Reactjs) · 架構演化站列出的 micro-frontend、BFF、CDN、SSR,在這站被接成一條由驗證時間驅動的推理鏈
- 接著看 ←15 Frontend Concepts Every Senior Dev Has Mastered · SSR、hydration、RSC 在這站只講概念,那站攤開整條架構演化與取捨
- 接著看 →Real Frontend System Design (from a Senior Engineer) · SSR、CDN、GraphQL、微前端在架構演化站被系統性建立,這站當成可選零件逐層裝上
- 接著看 ←Frontend System Design at Scale (The Senior Dev Playbook) · micro-frontend 與渲染策略在那站被展開成一條「解決什麼、製造什麼」的演化鏈
- 相關 —15 Fullstack Concepts Every Frontend Should Know · 共用 GraphQL 與 N+1:一站從協定往上推,一站從架構演化往下切
- 接著看 →The 3 Skills That Separate Architects From Senior Developers · 那站把架構演化與六軸取捨攤開,這站問誰來訂這些取捨、憑什麼訂
- 相關 —Vapor Mode is the Future of Vue · 架構演化史停在 vdom 時代,Vapor 是編譯派給出的下一站