前端系統設計面試:用心智模型把一個 client-server 架構逐層加壓到微前端

文字解析 · 1 支影片 · 產生於 2026-10-01 00:54

🎧 語音解析📝 筆記✍️ 練習

🎧 語音解析 1h00m · TTS 講解與作者原聲交錯;點章節可跳。
邊聽邊看逐句講稿,點任一句從那裡開始
章節(19)

1. Outline

  1. 起點 · Real Frontend System Design (from a Senior Engineer)
    從一句「來蓋 Amazon」開始,先拆功能/非功能需求並導出 UI 與狀態,再讓每一個非功能需求逼出一層新架構,最後停在微前端+monorepo 的組織級擴展。

2. YouTuber 的思維推導

Real Frontend System Design (from a Senior Engineer)

theSeniorDev · 48m25s · 字幕 en · vision=on (使用者指定 vision=true。影片是投影片+架構圖驅動的講解,每個 scale level 都以圖示呈現,逐張讀圖才能對照文字說明。) · YouTube

預估 vs 實際耗時
階段預估實際
fetch 6s 2s
segment 2m07s 4m40s
shot 1m49s 16s
analyze 20m00s 25m00s
render 5s –

作者的出發點是一個反直覺的主張:前端系統設計面試不該用「背範例」的方式準備,因為題目永遠換,只有心智模型能遷移。於是他選了一條可以一路走到底的敘事線:先把一句空泛的題目(「來蓋 Amazon」)拆成功能需求與非功能需求,用功能需求導出 UI 草稿,再從草稿逐塊抽出狀態、決定狀態該放在元件樹的哪一層,接著把狀態翻成 API 模型。走到這裡他刻意讓 REST 撞牆——一次瀏覽要打五支 API(under-fetching)——並宣告最陽春的 client-server 架構到此為止。

後半段他改用「加壓」的方式推進:每引入一個非功能需求,就逼出一層新架構。想快 → 先算出尖峰每小時 1.36 億頁面瀏覽的規模,再用光速與 TCP/TLS 來回次數證明延遲來自物理距離 → CDN(Level 1);動態內容也要快 → CSR 白畫面 → SSR → 邊緣運算 → 分散式唯讀資料庫(Level 3),並用 CAP 定理標出代價;要撐更多流量 → 先用快取消除請求,再加 API Gateway、BFF、GraphQL、負載平衡(Level 4);要好維護 → 康威定律說團隊結構決定系統結構,所以拆團隊就要拆系統 → 微前端,再用 design system 補回視覺一致、用 monorepo 補回工具鏈一致(Level 7)。最後用可用性(單點故障與 active-passive)、無障礙、資安三個較短的段落收邊,並補上 SEO 與可觀測性兩個加分題。

整條線的隱含結論是:架構不是一次選好的,而是被一個個非功能需求逼出來的;面試要展示的正是這個「被逼出來」的推理過程,而不是最終那張圖。

推理鏈:每段留給下一段的線索

每一列是一段,箭頭後的字是這段留給下一段的線索。點段落標題跳到該段。

  1. 別背題目,要學心智模型 → 路線圖畫好了,但第一階還沒開始:一句「來蓋 Instagram」要怎麼變成可以動手的東西?下一段從拆需求開始。
  2. 功能與非功能需求(飛機比喻) → 分類有了,但功能需求還只是一串句子。下一段要把它變成看得見的東西:一張 UI 草稿。
  3. 從使用者故事到低保真草稿 → 畫面有了,但畫面背後要記住哪些東西才能動起來?下一段開始從這張草稿上把狀態一塊一塊摳出來。
  4. 抽狀態與不可再簡測試 → 現在知道有哪些狀態了,但還不知道它們該放在元件樹的哪一層。下一段處理狀態的高度。
  5. 狀態的高度:lifting state → 狀態的位置定了,而且我們發現它之所以要抬高,是因為要拿去打 API。那 API 該長什麼樣?下一段開始建模。
  6. REST 建模與 under-fetching → 功能需求已經被一個 client-server 架構滿足了,但它撐不住規模。真正的系統設計從非功能需求開始——下一段先把非功能需求收斂成一張清單。
  7. 六大非功能需求與該問的問題 → 問題清單有了,但問完得到的是一堆數字。下一段示範怎麼把「每月 21.1 億次造訪」這種模糊大數,推成能決定架構的具體規模。
  8. 流量估算:back of the envelope → 規模算出來了,也知道沒有單一伺服器撐得住,而且七成流量在同一個頁面上。那第一個要處理的非功能需求是什麼?下一段從前端最優先的 web performance 開始。
  9. Core Web Vitals 與 UI 動靜光譜 → 光譜的靜態那端最容易處理,但要先知道慢是從哪裡來的。下一段從光速與網路實體結構開始算延遲。
  10. 網路延遲與 CDN(scale level 1) → 靜態資產的延遲解掉了,但畫面上會動的那一半還是得回伺服器。下一段處理動態內容的效能。
  11. 從白畫面到邊緣運算(scale level 3) → 效能這條線走完了,但整套架構的壓力全落在源站上。下一段換一個角度處理可擴展性:與其把請求送得更快,不如讓請求根本不發生。
  12. 用快取消除請求 → 能省的請求省完了,剩下的請求還是要打到後端,而後端已經是一堆微服務。下一段處理那些真的躲不掉的請求。
  13. API Gateway 與 BFF → 資料的入口整理好了,但第 6 段那個「一次瀏覽打五支 API」的問題還沒真正解掉,而且流量現在全壓在 BFF 上。下一段同時處理這兩件事。
  14. GraphQL 與水平擴展(scale level 4) → 到這裡效能與可擴展性都有解了,但整個前端仍然是一整塊、由一個大團隊維護。下一段換一個維度:可維護性。
  15. 康威定律與微前端(scale level 5) → 系統拆開了,團隊也小了,但立刻出現兩個新問題:各自為政會長得不一樣,換團隊的人也會迷路。下一段補這兩個洞。
  16. Design system 與 monorepo → 效能、可擴展性、可維護性都有了,但整張架構圖裡還藏著幾個「壞掉就全倒」的位置。下一段檢查可用性。
  17. 可用性、單點故障與 active-passive → 拓撲層面的問題到此收束。剩下兩個非功能需求靠的不是架構而是實作紀律——下一段處理無障礙與資安。
  18. 無障礙與資安速查 → 六項非功能需求都處理完了。最後還有兩個常被追問的加分題——下一段收尾。
  19. SEO 與前端可觀測性

3. 逐段說明

Real Frontend System Design (from a Senior Engineer)

1. 別背題目,要學心智模型 0:00–0:58

作者先否定「背 Spotify、Instagram 怎麼做」這類準備法,主張前端系統設計面試該練的是可遷移的心智模型。他預告全片會走過 web performance、前端可擴展性、無障礙、大型狀態建模、SSR 與邊緣運算,並用一條主線把架構從最基本的 client-server 一路加壓到 scale level 7(微前端、微服務、負載平衡、CDN、design system)。

全片路線圖:從 client-server 到 scale level 7 的階梯,是後面所有段落的骨架
0:45 · 全片路線圖:從 client-server 到 scale level 7 的階梯,是後面所有段落的骨架
承上 前情提要裡最關鍵的背景是:前端系統設計面試沒有標準答案,題目每次都不同。作者一開場就拿這個背景當槓桿,否定「背 Spotify 怎麼做」的準備法。

推理因為題目會換而模型不會換,所以作者把整支影片的目標訂成「交給你一組可遷移的心智模型」,並先攤開路線圖:web performance、前端可擴展性、無障礙、大型狀態建模、SSR、邊緣運算,最後用一條 scale level 的階梯把這些東西串起來,從最陽春的 client-server 一路加到微前端、微服務、負載平衡、CDN、design system。

AI 補充這個開場其實已經預告了全片的敘事結構:不是「介紹七個技術」,而是「同一個系統被加壓七次」。畫面上的 scale level 卡片是階梯的第一階,之後每加一個非功能需求,畫面就會回到同一張架構圖再長出一塊。要留意的是這套 level 編號是作者自創的教學工具,不是業界標準,面試時可以借用它的順序來組織回答,但不必背編號。另外作者說的是「用在任何面試」,實際上這條線也直接對應真實專案的演進順序——多數團隊都是先有 client-server,再被效能與人數逼著往上加。

mental model

心智模型

一套可以套用到不同題目上的思考框架,而不是某個題目的標準答案。

系統設計面試考的是推理過程,因為面試官知道你沒做過 Amazon。心智模型的價值在於「壓縮」:把幾十個技術決策壓成幾個可以在白板上依序展開的問題(要滿足誰?要多快?要多少人維護?)。判斷你手上的是不是心智模型,方法是換一個題目再用一次——若換題就失效,那是記憶而不是模型。

相關術語: scale level (本片的具體形式)

出處:第 1 段「別背題目,要學心智模型」

scale level

擴展階層

作者用來標記架構複雜度的階梯,每一階對應多滿足一組非功能需求後長出來的新元件。

這是本片自創的教學編號,不是業界術語。它的用處在於讓「架構演進」變成可敘述的順序:Level 0 是純 client-server,加 CDN 是 Level 1,加邊緣運算與分散式資料庫是 Level 3,加 API Gateway/BFF/負載平衡是 Level 4,拆微前端是 Level 5,再加 monorepo 是作者口中的 Level 7。編號中間有跳號,記順序即可,不必記數字。

相關術語: mental model (一種)

出處:第 1 段「別背題目,要學心智模型」

留給下一段 路線圖畫好了,但第一階還沒開始:一句「來蓋 Instagram」要怎麼變成可以動手的東西?下一段從拆需求開始。

2. 功能與非功能需求(飛機比喻) 0:58–2:50

面試通常以一句很空的「來蓋 Instagram」開場,第一步是把它拆成需求。作者用飛機比喻分兩類:功能需求是飛機要有的座位、起落架、引擎,也就是它要完成什麼;非功能需求是航程、油耗、碳排、落地噪音,也就是它怎麼做到。對應到前端,功能需求由使用者看得到、摸得到的 UI 滿足,非功能需求則是效能、可擴展性、安全性。

功能 vs 非功能需求的飛機對照圖,是全片需求分類的定錨
1:40 · 功能 vs 非功能需求的飛機對照圖,是全片需求分類的定錨
承上 上一段留下的問題是「一句空泛的題目要怎麼開始」。這一段給出第一個動作:把那句話拆成兩類需求。

推理因為要讓「需求」這個抽象詞可操作,所以作者換成飛機當載體:座位數、起落架、引擎、機身結構是功能需求,也就是這架飛機「要做到什麼」;航程、平均油耗、碳排、落地噪音是非功能需求,也就是它「怎麼做到」。接著他把比喻收回前端:功能需求由使用者看得到、摸得到的 UI 滿足,非功能需求則落在效能、可擴展性、安全性這些看不見的地方。

AI 補充這個切法之所以重要,是因為它決定了面試前半場與後半場的分工:功能需求會產出畫面與資料結構,非功能需求會產出架構。很多人卡住是因為把兩者混著談——一邊畫 UI 一邊講 CDN,結果兩邊都講不深。飛機比喻還藏了一個好用的檢查:非功能需求幾乎都可以被量化(航程幾公里、油耗幾公升),所以當你講不出數字時,通常代表你把它當成形容詞在講(「要很快」),而不是當成需求在談。

functional requirement

功能需求

系統要提供什麼能力,對應使用者做得到哪些事。

在前端,功能需求幾乎等同「UI 上有什麼、可以按什麼」。它的驗收方式是二元的:使用者能不能加入購物車?能或不能。這與非功能需求的驗收方式(幾毫秒、幾個 9)完全不同,也是為什麼兩者要分開談。

相關術語: non-functional requirement (對照組)

出處:第 2 段「功能與非功能需求(飛機比喻)」

non-functional requirement

非功能需求

系統要以什麼品質做到那些事,例如多快、能撐多少人、多安全、多好維護。

縮寫 NFR。它們是架構的真正驅動力——功能需求幾乎不會改變架構(多一個按鈕不會讓你需要 CDN),非功能需求才會。實務上 NFR 通常需要主動問出來,因為需求方預設它們理所當然(「當然要快啊」),而「快」在部落格與交易系統是完全不同的工程。

相關術語: functional requirement (對照組)、scale level (驅動)

出處:第 2 段「功能與非功能需求(飛機比喻)」

留給下一段 分類有了,但功能需求還只是一串句子。下一段要把它變成看得見的東西:一張 UI 草稿。

3. 從使用者故事到低保真草稿 2:50–4:16

作者以 amazon.com 的商品列表頁當範例,把功能需求寫成使用者故事:瀏覽商品、加入購物車、評分評論、線上下單付款。從這些故事就能導出第一版 UI,也就是低保真 mockup;有些面試會直接給你,有些要你自己畫。這張草稿是後面抽狀態、設計 API 的唯一依據。

amazon 商品列表頁的低保真 mockup,後面抽狀態、切元件、切微前端都指著這張圖
3:55 · amazon 商品列表頁的低保真 mockup,後面抽狀態、切元件、切微前端都指著這張圖
承上 上一段把需求分成兩類,並指出功能需求由 UI 滿足。這一段就把那個 UI 生出來。

推理因為功能需求要落地成畫面,所以作者選 amazon.com 的商品列表頁當範例,先把功能需求寫成幾條使用者故事——瀏覽商品、加入購物車、評分與評論、線上下單付款——再從這些故事畫出第一版低保真 mockup。他也提醒:有些面試會直接給你這張圖,有些要你自己畫。

AI 補充選商品列表頁不是隨手挑的,作者後面會用數據證明它是流量最集中的頁面;先鎖定一個頁面,是為了讓後續每個決策都有具體對象可以指。另一個值得學的動作是「低保真」三個字:面試中畫得越精緻越浪費時間,草稿只需要能讓你指著某一塊說「這裡需要一個狀態」。這張圖在後面會被反覆使用——抽狀態指它、算讀寫比例指它、切微前端也指它——所以它其實是整場面試的共用座標系。

術語:low-fidelity mockup

user story

使用者故事

用「使用者可以做什麼」的句子描述一條功能需求。

格式通常是「作為某種使用者,我可以做某事,以便達成某個目的」。在系統設計面試裡它的作用是收斂範圍:把「蓋 Amazon」縮成四五條可以畫成畫面的句子,同時給你一個合法的理由把購物車、金流之類的部分明講「留在範圍外」。

相關術語: low-fidelity mockup (產出)

出處:第 3 段「從使用者故事到低保真草稿」

low-fidelity mockup

低保真草稿

只有區塊與位置、沒有視覺細節的 UI 草圖。

低保真的重點是刻意不畫細節,讓討論停留在結構層次。在系統設計面試中它是後續所有推理的錨點:狀態從它身上抽、資料模型從它身上長、快取策略也是逐塊看它決定。畫完後最好在上面標編號或命名區塊,之後你才能用「這塊」來指涉,而不用重複描述。

相關術語: user story (由它導出)

出處:第 3 段「從使用者故事到低保真草稿」

留給下一段 畫面有了,但畫面背後要記住哪些東西才能動起來?下一段開始從這張草稿上把狀態一塊一塊摳出來。

4. 抽狀態與不可再簡測試 4:16–6:11

狀態要越少越好,因為狀態佔記憶體又會觸發 re-render。從 mockup 逐塊掃出需要的狀態:品牌清單的 loading/error/data、使用者選的品牌、購物車、分頁、商品列表的 loading/error/data。抽完後跑「不可再簡測試」——試著拿掉任一個狀態變數,若 UI 就做不出來,才確定它是必要狀態。接著把它們落成實際資料結構:狀態原始值(selected brand、current page)與領域實體(product、product brand)。

從 UI 逐塊標出狀態的對照圖,示範怎麼「看著畫面抽狀態」
5:00 · 從 UI 逐塊標出狀態的對照圖,示範怎麼「看著畫面抽狀態」
整理後的資料結構清單:state primitives 與 domain entities 的分野
5:50 · 整理後的資料結構清單:state primitives 與 domain entities 的分野
承上 上一段畫出了低保真草稿,並說它是後續推理的座標系。這一段就在這張圖上動第一刀:把狀態摳出來。

推理因為狀態既佔記憶體又會觸發 re-render,作者先立下「越少越好」的原則,再帶著這個原則逐塊掃過草稿:品牌清單要從後端抓,於是有 loading / error / data;使用者要勾選品牌,是使用者互動造成的狀態;購物車、分頁同理;商品列表本身又是一組 loading / error / data。抽完後他加了一道驗收動作——不可再簡測試——逐一嘗試拿掉每個狀態變數,若 UI 仍能運作,那個狀態就不是必要的。最後把結果落成兩類資料:狀態原始值(selected brand 是字串或字串陣列、current page 是數字)與領域實體(product、product brand)。

AI 補充畫面上那張圖把每個箭頭標成 Data Fetching 或 User Interaction,這其實是一個實用的分類法:狀態的來源只有兩種——外部資料進來,或使用者動作進來。用這兩個標籤掃過畫面,比憑感覺列狀態更不容易漏。不可再簡測試看起來像形式,實際上它擋掉的是最常見的錯誤:把「可以算出來的東西」存成狀態(例如把篩選後的商品陣列另存一份,而它其實是商品陣列加上選中品牌的推導結果)。作者也示範了面試裡合法的減負動作——他直接宣告購物車狀態超出範圍——這在真實面試中通常會被接受,但要主動說出口,而不是默默略過。

state

狀態

為了畫出目前這個畫面,程式必須記住的最小資訊。

定義裡的「最小」是關鍵字:能從別的狀態推導出來的東西不是狀態,是衍生值。狀態的成本有兩層——佔記憶體,以及每次改變都可能引發重新渲染——所以狀態設計的目標永遠是找到那組不能再少的集合。

相關術語: irreducibility test (由它驗收)、domain entity (另一種資料)

出處:第 4 段「抽狀態與不可再簡測試」

irreducibility test

不可再簡測試

逐一拿掉每個狀態變數,確認少了它 UI 就做不出來,藉此證明這組狀態是必要的。

它是「單一真相來源」原則的操作版本。實務上最常被它抓出來的是三類冗餘:可推導的衍生值、和 URL 或後端重複的副本、以及為了方便而多存的快照。做完這個測試,後面的資料流會簡單很多,因為每個畫面上的值都只有一個出處。

相關術語: state (驗收對象)

出處:第 4 段「抽狀態與不可再簡測試」

domain entity

領域實體

業務上有身分、需要被辨識與追蹤的物件,例如 product、product brand。

與狀態原始值(一個數字、一個字串)不同,領域實體有 id、有生命週期、通常對應後端的一張表或一個資源。分清這兩者的好處是:狀態原始值屬於這個畫面,換頁就沒了;領域實體屬於整個系統,會出現在 API、快取、型別定義裡。作者提到面試中你被期待能從一張畫面裡認出聚合與實體,但不必展開完整的領域設計。

相關術語: state (對照組)

出處:第 4 段「抽狀態與不可再簡測試」

留給下一段 現在知道有哪些狀態了,但還不知道它們該放在元件樹的哪一層。下一段處理狀態的高度。

5. 狀態的高度:lifting state 6:11–9:02

狀態有三種高度:local、shared local、global,複雜的轉換各自可再套 reducer pattern。元件樹是倒著長的,使用者看到的是最底層的葉子,所以狀態應該放在真正用到它的最底層,能不往上抬就不抬。原則是「as low as possible, as high as necessary」。回到範例,current page 要拿去打 API,得抬到與商品資料請求同層;品牌篩選也會影響同一個請求,於是三者都被抬成同層的 shared local state。

state altitude 三層圖:local / shared local / global
7:00 · state altitude 三層圖:local / shared local / global
分頁、品牌篩選、商品資料被抬到同層的元件樹圖,是 lifting 原則的實例
8:25 · 分頁、品牌篩選、商品資料被抬到同層的元件樹圖,是 lifting 原則的實例
承上 上一段抽出了必要狀態,也留下「它們該放在哪一層」這個問題。這一段給出判準。

推理因為要談位置,作者先把位置變成三個刻度:local、shared local、global,並補一句每一層都可以在轉換複雜時套用 reducer pattern。接著他用一個反直覺的圖說明元件樹是倒著長的——使用者看到的是最底部的葉子——所以狀態應該從最底層開始放,能不抬就不抬,原則是「as low as possible, as high as necessary」。回到範例,current page 必須拿去打 API,所以要抬到與商品資料請求同層;品牌篩選也會影響同一個請求,於是三個狀態最後都被抬成同層的 shared local state。

AI 補充這裡有一個容易被略過的因果:狀態被抬高不是因為「很多元件想用」,而是因為它成了某個副作用(這裡是 API 請求)的輸入。找到那個副作用發生的位置,狀態的高度就確定了,不必憑感覺猜。另外作者只說了 global state 的例子是驗證資訊,沒說的是抬高的代價——每次改變會讓整個子樹重算,這正是第 4 段講的「狀態會觸發 re-render」在架構層的回音,也是為什麼要用 as low as possible 當預設。至於這段結尾那句「先讓狀態很 global 再往上抬」,方向與他整段的主張相反,實際做法是相反的:從最低層開始,只在必要時往上。

術語:lifting state

lifting state

狀態上抬

把狀態從使用它的元件往上移到共同的祖先,讓多個元件能共用同一份資料。

作者稱它是必要之惡:每抬一層,重新渲染的範圍就變大一圈,能讀寫它的程式也變多一圈。判斷該不該抬的實用問題不是「誰會用到」,而是「哪個位置能同時看到所有需要它的兄弟元件與它引發的副作用」。當抬到頂層還不夠、或跨路由都要用時,才輪到全域狀態管理工具。

相關術語: component tree (移動的軌道)、global state (抬到極限)

出處:第 5 段「狀態的高度:lifting state」

component tree

元件樹

元件彼此巢狀構成的樹狀結構,根在頂、使用者看到的畫面在葉子。

作者用「倒過來的樹」形容它:真實的樹是根在下葉在上,元件樹是根在上葉在下,而使用者看到的正是最下面那圈葉子。這個圖像的用處是讓「上/下」有一致的方向感——往上=離畫面更遠、影響範圍更大;往下=更靠近使用者、影響範圍更小。

相關術語: lifting state (發生於其上)

出處:第 5 段「狀態的高度:lifting state」

reducer pattern

reducer 模式

把狀態變更集中成「目前狀態 + 動作 → 新狀態」的純函式,取代散落各處的直接賦值。

適用時機是狀態轉換有規則、有先後、或多個欄位必須一起改(例如送出表單時同時要清錯誤、鎖按鈕、設 loading)。它與狀態放在哪一層是兩個獨立的決定——local、shared、global 三層都可以用 reducer。好處是所有可能的變化都列在一個地方,壞處是簡單狀態用它會變囉嗦。

相關術語: state (管理方式)

出處:第 5 段「狀態的高度:lifting state」

global state

全域狀態

整個應用都可能讀取的狀態,例如登入身分與權限。

判準不是「很多地方用」,而是「幾乎任何位置都可能需要,且它與畫面結構無關」。驗證資訊是典型例子:header 要顯示名字、路由要擋未登入、API 層要帶 token。反例是搜尋關鍵字——看起來到處都用,其實只屬於搜尋頁那棵子樹。

相關術語: lifting state (極端情況)

出處:第 5 段「狀態的高度:lifting state」

見仁見智 9:02
「make sure you start with your state being very global and then raise it as high as necessary but as low as possible」
這句把方向講反了。同一段前面的原則是「as low as possible, as high as necessary」——從元件樹最低層開始放,只在有共用需求或副作用需要時才往上抬。照字面「start with your state being very global」做,會得到一份什麼都在頂層的狀態,正是這段要避免的結果。
依據: 同段 8:06 前後作者自己的表述:lifting state is a necessary evil, only if it's really necessary
留給下一段 狀態的位置定了,而且我們發現它之所以要抬高,是因為要拿去打 API。那 API 該長什麼樣?下一段開始建模。

6. REST 建模與 under-fetching 9:02–13:26

把狀態翻成後端 API:先用 REST 觀點看待 product、product brand 這些實體。細看會發現單一 product 實體撐不住——價格常變、評分由評論算出、送達時間隨地址重算——於是一個實體被拆成五個,各自有自己的 REST endpoint,篩選與分頁一律用 query parameter 掛在同一個 endpoint 上。代價是:一次頁面瀏覽至少要打五支後端 API,這就是 REST 的 under-fetching。到這裡功能需求已能被最陽春的 client-server 架構滿足,但它撐不住規模。

一個 product 實體被拆成五個實體的演變圖,說明為什麼會產生多次請求
10:40 · 一個 product 實體被拆成五個實體的演變圖,說明為什麼會產生多次請求
拆出來的 REST endpoint 清單與巢狀關係
11:15 · 拆出來的 REST endpoint 清單與巢狀關係
五次後端呼叫的 under-fetching 示意,是後面 GraphQL/BFF 的伏筆
12:40 · 五次後端呼叫的 under-fetching 示意,是後面 GraphQL/BFF 的伏筆
最陽春的 client-server 架構圖,全片架構演進的起點
13:10 · 最陽春的 client-server 架構圖,全片架構演進的起點
承上 上一段的結論是狀態被抬高是為了打 API。這一段就接著問:那支 API 要長什麼樣,才餵得飽這些狀態?

推理因為狀態要翻成後端契約,作者先用 REST 的眼光看待前面抽出的實體,把 product 展開成 price、name、description、rating、category、deliveryTime。展開後問題就浮出來:價格會頻繁變動且有幣別、評分是由評論算出來的、送達時間隨使用者地址即時重算——這三個都不該壓在 product 這一層。於是一個實體被拆成五個,各自有自己的 endpoint,而篩選與分頁不另開端點,一律用 query parameter 掛在原本的資源上。最後他把代價點名:一次前端頁面瀏覽至少要打五支後端 API,這就是 under-fetching,並宣告最陽春的 client-server 架構到此為止。

AI 補充拆實體的判準值得單獨記住:不是「欄位多不多」,而是「這個欄位的變動頻率、生命週期、計算來源和主體一不一樣」。價格會單獨改、評分是聚合結果、到貨時間依賴另一個輸入(地址),三者都不屬於 product 自己的生命週期,所以各自獨立。這條判準在後端叫聚合邊界,在前端則直接決定你要打幾支 API、能不能分別快取,後面談快取策略時會再用到同一組資訊。要注意 under-fetching 是 REST 資源導向的必然結果而不是設計失誤:資源分得越乾淨,一個畫面要組的資源就越多。作者在這裡刻意讓 REST 撞牆,是因為它是後面 BFF 與 GraphQL 的動機來源。

術語:client-server architecture

REST

REST 架構風格

把後端能力表達成一組資源,用統一的 HTTP 動詞(GET/POST/PATCH/DELETE)操作它們。

REST 的核心賣點是介面統一:你只要知道資源的名字,就知道怎麼讀它、改它、刪它,不必為每個功能學一組新方法。代價是資源的邊界由後端的領域決定,而畫面需要的資料組合由前端決定,兩者不一致時前端就得自己拼——這正是 under-fetching 的來源。

相關術語: endpoint (組成單位)、under-fetching (常見副作用)

出處:第 6 段「REST 建模與 under-fetching」

endpoint

端點

一個資源對外的網址,例如 /products/:productId。

REST 允許用巢狀表達從屬關係(/products/:productId/prices/:priceId 表示這個價格屬於這個商品)。設計時的常見取捨是巢狀多深:越深語意越清楚,但也越難重用——當同一個資源有多個父層時,通常會改成獨立端點加參數。

相關術語: query parameter (搭配使用)

出處:第 6 段「REST 建模與 under-fetching」

query parameter

查詢參數

掛在端點後面的鍵值對,用來分頁、篩選、排序同一個資源集合。

關鍵原則是:分頁與排序不是新資源,所以不開新端點。/products?page=1&pageSize=10 與 /products?sort=price 指的都是同一個集合的不同切片。這也是為什麼第 5 段的 current page 必須抬到打 API 的那一層——它其實是 URL 的一部分。

相關術語: endpoint (掛在其上)

出處:第 6 段「REST 建模與 under-fetching」

under-fetching

取得不足

一次請求拿不到畫面需要的全部資料,必須再打好幾支 API 才能湊齊。

它是資源導向 API 的結構性後果,不是誰寫錯了。後果有兩層:對使用者是多輪來回造成的延遲,對後端是請求量被放大。相對的問題是 over-fetching——為了一個欄位拿回整包資料,行動網路上特別浪費。兩者是同一組取捨的兩端,也是 GraphQL 想同時解掉的東西。

相關術語: REST (來自)

出處:第 6 段「REST 建模與 under-fetching」

client-server architecture

主從式架構

一個前端客戶端直接對一個後端伺服器要資料的最基本架構。

作者把它標成 Level 0:足以滿足全部功能需求,卻幾乎不滿足任何非功能需求。它的價值在於當基準線——後面每加一個元件(CDN、邊緣函式、API Gateway、BFF、負載平衡),都可以說清楚是為了解決哪一個具體問題,而不是因為它們流行。

相關術語: scale level (第 0 階)

出處:第 6 段「REST 建模與 under-fetching」

留給下一段 功能需求已經被一個 client-server 架構滿足了,但它撐不住規模。真正的系統設計從非功能需求開始——下一段先把非功能需求收斂成一張清單。

7. 六大非功能需求與該問的問題 13:26–15:52

非功能需求關心使用者分布、裝置、法規、以及變更成本。作者收斂成六項:web performance、client scalability、availability/fault tolerance、web accessibility(A/AA/AAA)、maintainability、web security。他強調資深度不只看你答什麼,更看你問什麼,並示範一串好問題:預期流量多少、有無時段或地理的分布差異、有無 Prime Day 這種尖峰、使用者主要用什麼瀏覽器與裝置、載入速度是否關鍵、無障礙有無法規要求、有無特殊資安考量。

六大非功能需求總表,是後半段所有章節的目錄
13:50 · 六大非功能需求總表,是後半段所有章節的目錄
面試中該問的問題清單,可直接背下來用
15:00 · 面試中該問的問題清單,可直接背下來用
承上 上一段用 under-fetching 證明陽春架構撐不住,並把非功能需求推到台前。這一段先把它們列成可討論的清單。

推理因為非功能需求太發散,作者先框出它們關心什麼——使用者是誰、分布在哪、用什麼裝置、有無法規、以及變更成本——再收斂成六項:web performance、client scalability、availability 與 fault tolerance、web accessibility、maintainability、web security。接著他轉了一個彎:資深度不只由答案決定,也由你問的問題決定,於是給出一串可以直接背的提問——預期多少流量、有無時段或地理分布差異、有無 Prime Day 這種尖峰、主要瀏覽器與裝置是什麼、載入速度是否關鍵、無障礙有無法規要求、有無特殊資安顧慮。

AI 補充這六項不是隨意排序的,它們正好是本片後半段的章節目錄,而且順序有意義:效能與可擴展性先談,因為它們會改變架構圖;可維護性接在後面,因為它改變的是團隊與 repo;無障礙與資安放最後,因為它們主要靠實作紀律而不是拓撲。至於那串提問,真正的價值不在禮貌,而在於每個問題都會夾住一個後面要做的決策——問裝置是為了決定 bundle 預算與圖片尺寸,問尖峰是為了決定要不要為峰值容量付錢,問法規是為了決定無障礙要做到哪一級。作者提到無障礙的等級時把 A / AA / AAA 唸得含糊,記住三級即可:A 是最低、AA 是多數法規要求的水準、AAA 最嚴格。

scalability

可擴展性

使用者或流量增加時,系統仍能維持效能,最好連程式碼都不必改。

定義裡「不必改程式」這半句常被忽略,但它才是區分「加機器就能撐」與「要重寫」的分界。前端的可擴展性和後端不同:前端的瓶頸多半不是自己的 CPU,而是每個使用者都要下載的資產與每個畫面引發的請求量,所以擴展手段偏向消除請求(快取、CDN)而不是加實例。

相關術語: non-functional requirement (屬於)、maintainability (並列)

出處:第 7 段「六大非功能需求與該問的問題」

fault tolerance

容錯

系統中某個元件失效時,整體仍能繼續服務或自行復原的能力。

它與可用性是一體兩面:可用性是結果(有多少時間能用),容錯是手段(壞了會怎樣)。前端能談的容錯多半來自分布——多個 edge location、多個實例、多份唯讀副本,任一個壞掉都能改導到其他健康節點。真正危險的是那些只有一份的元件。

相關術語: scalability (常同手段)

出處:第 7 段「六大非功能需求與該問的問題」

maintainability

可維護性

系統被擴充與修改的容易程度,也就是變更成本。

它是六項裡唯一不是技術指標而是組織指標的:同一份程式碼,三個人維護和四十五個人維護的難度完全不同。這也是為什麼作者後面談可維護性時,端出來的不是某個函式庫,而是康威定律與團隊拆分。量測方式通常是變更前置時間與部署頻率,而不是程式碼行數。

相關術語: non-functional requirement (屬於)

出處:第 7 段「六大非功能需求與該問的問題」

留給下一段 問題清單有了,但問完得到的是一堆數字。下一段示範怎麼把「每月 21.1 億次造訪」這種模糊大數,推成能決定架構的具體規模。

8. 流量估算:back of the envelope 15:52–19:10

作者查出 amazon.com 每月來自美國約 21.1 億次造訪,東西岸分布平均,週二到週四為高峰、晚上 7 到 10 點是尖峰時段,7 成以上流量來自行動裝置。接著逐步收斂:月 21.1 億 → 週 5 億 → 週二到四 2.5 億 → 週四 1.25 億 → 尖峰小時 2100 萬次造訪,再乘上每次造訪平均 6.8 個頁面,得到尖峰每小時約 1.36 億次頁面瀏覽。重點不是數字精準,而是能把一個模糊的大數推到具體的每秒/每小時請求量。另外 59% 購買發生在行動裝置、70% 造訪落在商品搜尋頁,決定了後續最佳化的戰場。

流量、地理、時段、裝置的原始數據表,是估算的輸入
16:40 · 流量、地理、時段、裝置的原始數據表,是估算的輸入
從月造訪逐步除到尖峰小時的推導鏈,這段的核心方法
17:30 · 從月造訪逐步除到尖峰小時的推導鏈,這段的核心方法
1.36 億頁面瀏覽/小時的結論,說明為何單台伺服器必然不夠
18:20 · 1.36 億頁面瀏覽/小時的結論,說明為何單台伺服器必然不夠
承上 上一段留下的問題是:問到流量數字之後要拿它做什麼。這一段就示範怎麼把大數推成能決定架構的規模。

推理因為「21.1 億」本身不能決定任何事,作者先補齊四項條件:來自美國的月造訪 21.1 億、地理分布平均、週二到週四為高峰且晚上七到十點是尖峰、行動裝置佔七成以上。接著逐步收斂:月 21.1 億 → 週 5 億 → 週二至四 2.5 億 → 週四 1.25 億 → 尖峰小時 2100 萬次造訪;再乘上每次造訪平均 6.8 個頁面,得到尖峰每小時約 1.36 億次頁面瀏覽。他強調重點不是算得準,而是能把模糊大數推到具體的每小時/每秒請求量,並在推導中和面試官一起講清楚每一步的假設。最後兩個數字定了戰場:59% 的購買發生在行動裝置、70% 的造訪落在商品搜尋頁。

AI 補充這段的方法論比數字重要:每一步都是「總量 × 一個佔比」,而每個佔比都來自上一段問出來的問題。這也是為什麼提問要先做——沒有那些分布資訊,你只能停在月造訪數,推不出尖峰。值得補的是這個推導刻意保守:它假設週內與時段的集中度只有 50%,實際電商的尖峰集中度通常更高,而 Prime Day 這類事件作者直接排除在外,因為為峰值容量長期付費是另一個成本決策。行動佔比則同時決定了兩件事——JavaScript 要輕(CPU 弱)、圖片可以更小(螢幕窄),後者反而是可以拿來占便宜的地方。

術語:back of the envelope calculationdimensional analysis

back of the envelope calculation

信封背面估算

用少數幾個假設做的粗略量級推算,目的是把模糊的大數變成能決定架構的具體數字。

它的成功標準是量級對,不是小數點對。做法是把一個大數沿著時間、地理、裝置等維度逐層切分,每切一刀就講出一個假設。在面試中它同時是溝通工具:面試官真正在看的是你會不會主動說出假設,以及在假設被推翻時能不能重算。

相關術語: dimensional analysis (同源方法)

出處:第 8 段「流量估算:back of the envelope」

dimensional analysis

量綱分析

傳統工程中用單位換算與量級推導檢查結果是否合理的方法。

作者拿它來類比信封背面估算:兩者都靠單位串接(次/月 → 次/週 → 次/小時 → 頁/小時),而單位對不上就代表推理有洞。實用的檢查習慣是:每寫下一個數字就寫下它的單位,最後看單位有沒有自然約掉成你要的那個。

相關術語: back of the envelope calculation (類比對象)

出處:第 8 段「流量估算:back of the envelope」

留給下一段 規模算出來了,也知道沒有單一伺服器撐得住,而且七成流量在同一個頁面上。那第一個要處理的非功能需求是什麼?下一段從前端最優先的 web performance 開始。

9. Core Web Vitals 與 UI 動靜光譜 19:10–21:34

前端系統設計與後端最大的差別,是第一順位話題是 web performance,而它只有兩件事:載入多快、回應輸入多快。量化方式是 Core Web Vitals,作為前端的 SLI(service level indicator):LCP 與 CLS 管初次載入,INP 管重新渲染與互動回應。接著作者提出關鍵提問——你的 UI 有多靜態或多動態?從媒體/部落格(極靜)、電商(靜中帶動)、社群(大量互動)到企業 SaaS 與 Uber(極動),不同位置決定了要用哪種最佳化手段。

三個 Core Web Vitals 與它們各自量的東西
19:50 · 三個 Core Web Vitals 與它們各自量的東西
從媒體到企業 SaaS 的靜態—動態光譜圖,決定後續策略分岔
20:50 · 從媒體到企業 SaaS 的靜態—動態光譜圖,決定後續策略分岔
承上 上一段算出尖峰每小時 1.36 億次頁面瀏覽,且七成集中在商品搜尋頁。這一段開始處理第一個非功能需求:這個頁面要多快。

推理因為前端與後端系統設計的第一順位不同,作者先把 web performance 推到最前面,並把它拆成兩件事:載入多快、回應輸入多快。為了讓它可討論,他引入 Core Web Vitals 當作前端的 SLI——LCP 與 CLS 管初次載入,INP 管互動回應。接著他丟出決定後續路線的提問:你的 UI 有多靜態或多動態?並畫出一條光譜,從媒體與部落格(幾乎全靜態)、電商(內容多但互動也多)、社群(大量使用者產生內容與即時互動),一路到企業 SaaS 與 Uber(狀態極多、內容極少)。

AI 補充這條光譜是全片的分岔點:靜態那端靠複製資產解決(下一段的 CDN),動態那端靠移動運算解決(SSR 與邊緣運算),而電商剛好卡在中間,所以兩套都得做——這正是作者選 Amazon 當例子的理由。另外要分清 SLI 和 SLO 的差別:Core Web Vitals 是指標本身(量出多少),你還需要一條目標線(例如 LCP 的 p75 要在 2.5 秒內)才構成目標。也要注意這些指標是以真實使用者的分布來看的,用自己的筆電量出來的數字通常過於樂觀,要靠真實使用者端的監控才補得上這一塊。

Core Web Vitals

核心網頁指標

Google 定義的一組真實使用者體驗指標,用來量化頁面載入速度與互動回應速度。

目前的三項是 LCP、CLS、INP(INP 於 2024 年 3 月取代了先前的 FID)。它們的共同特色是從真實使用者端收集,而不是實驗室跑分,因此會反映出低階手機與弱網路的長尾。除了體驗本身,它們也影響 Google 搜尋排名,這條連結在最後談 SEO 時會再被用上。

相關術語: SLI (是一種)、LCP (包含)

出處:第 9 段「Core Web Vitals 與 UI 動靜光譜」

SLI

服務等級指標

把非功能需求變成可量測數字的指標,例如延遲、吞吐量、可用性。

全名 service level indicator。它是三兄弟裡最基礎的一個:SLI 是量到的數字,SLO 是你自己訂的目標(例如 99.9% 的請求在 300ms 內),SLA 是對客戶承諾違約要賠的合約。面試中把「要很快」翻譯成一條 SLI 加一個目標值,是最快展現資深度的動作之一。

相關術語: non-functional requirement (量化)

出處:第 9 段「Core Web Vitals 與 UI 動靜光譜」

LCP

最大內容繪製

頁面上最大的那塊內容(通常是主圖或標題)被畫出來的時間點。

全名 Largest Contentful Paint,代表「使用者覺得主要內容出現了」的時刻。它會被三件事拖慢:伺服器回應太久、資源被 render-blocking 擋住、圖片太大或載入太晚。這也是為什麼後面 CDN 與 SSR 兩招都能直接改善它。

相關術語: Core Web Vitals (其中一項)

出處:第 9 段「Core Web Vitals 與 UI 動靜光譜」

CLS

累積版面位移

頁面載入過程中版面意外跳動的累積量。

全名 Cumulative Layout Shift。典型成因是圖片或廣告沒先預留尺寸,內容載入後把下方元素推開,使用者剛要點的按鈕就跑掉。它是三項裡最容易靠紀律解決的——給媒體元素明確的寬高或長寬比即可。

相關術語: Core Web Vitals (其中一項)

出處:第 9 段「Core Web Vitals 與 UI 動靜光譜」

INP

互動到下一次繪製

使用者互動後,畫面實際更新所需的時間。

全名 Interaction to Next Paint,2024 年 3 月正式取代 FID 成為互動性的核心指標。與 FID 只看第一次互動的輸入延遲不同,INP 看整個頁面生命週期中的互動,而且量到的是「按下去到看見反應」的完整時間,因此主執行緒被長任務塞住時會直接反映出來,這也是後面把分析工具丟給背景執行緒的理由。

相關術語: Core Web Vitals (其中一項)

出處:第 9 段「Core Web Vitals 與 UI 動靜光譜」

留給下一段 光譜的靜態那端最容易處理,但要先知道慢是從哪裡來的。下一段從光速與網路實體結構開始算延遲。

10. 網路延遲與 CDN(scale level 1) 21:34–24:28

先算物理極限:光纖中光速約每秒 30 萬公里,舊金山到紐約單程約 9 毫秒,人類感知「慢」的門檻是 100 毫秒,看似綽綽有餘。但實際封包要在多個交換節點間轉手,一次來回要 140–160 毫秒;TCP 建連要三次來回,加上 TLS 的 HTTPS 至少四次,光是建立連線就約 600 毫秒。消除這段延遲最簡單的方法是把靜態資產複製到離使用者最近的 edge location,這就是 CDN,也就是 scale level 1:client + server + CDN。

光速與跨美延遲的數字對照,建立「延遲從哪裡來」的直覺
22:10 · 光速與跨美延遲的數字對照,建立「延遲從哪裡來」的直覺
封包在多個節點間轉手的路徑圖,解釋 9ms 為何變成 140ms
22:45 · 封包在多個節點間轉手的路徑圖,解釋 9ms 為何變成 140ms
scale level 1 架構圖:加上 CDN 後的樣子
24:10 · scale level 1 架構圖:加上 CDN 後的樣子
承上 上一段把效能拆成載入與互動兩件事,並指出靜態那端最好處理。這一段先算清楚「慢」的物理來源。

推理因為要證明延遲不是程式寫得爛,作者從基礎設施算起:光纖裡光速約每秒 30 萬公里,舊金山到紐約約 2654 公里,單程約 9 毫秒,而人要覺得慢得超過 100 毫秒——看起來完全不是問題。接著他戳破這個樂觀:封包不會直線飛,要在一連串交換節點間轉手,一次來回實測約 140 到 160 毫秒;再加上 TCP 建連與 TLS 交握的來回次數,光是把連線建起來就要好幾百毫秒。既然延遲來自距離,最直接的解法就是把靜態資產複製到離使用者最近的節點,也就是 CDN,於是架構長到 Level 1:client + CDN + server。

AI 補充這段真正要教的是一個推理姿勢:先算物理下限,再看實際值差多少,差距就是可最佳化的空間。作者的具體數字要打點折——TCP 建立連線是一次來回(SYN、SYN-ACK 之後就能送資料),而 TLS 1.3 把交握壓到一次來回、續連甚至可以 0-RTT,所以現代 HTTPS 大約是兩次來回而不是四次;若走 HTTP/3(QUIC),TCP 與 TLS 的交握還會合併。但這不影響結論:來回次數乘上地理距離就是你付不起的成本,而縮短距離是唯一能同時砍掉每一次來回的手段。也要注意 CDN 在這一階只解靜態資產,動態路徑仍然要回源站,這個缺口是下一段的起點。

術語:network latency

network latency

網路延遲

一個封包從一端送到另一端所需的時間,理論下限是光速,實際遠慢於此。

延遲和頻寬是兩件事:頻寬決定一次能送多少,延遲決定要等多久才開始送到。加頻寬解不了延遲,因為延遲由距離與轉手次數決定。這也是為什麼所有降延遲的手段——CDN、邊緣運算、唯讀副本——本質上都是同一招:把東西搬近一點。

相關術語: CDN (用它降低)、TLS (交握放大它)

出處:第 10 段「網路延遲與 CDN(scale level 1)」

CDN

內容傳遞網路

把靜態資產複製到全球各地的節點,讓使用者就近取得,而不必回到源站。

全名 content delivery network。它的第一價值是降延遲,但附帶效果同樣重要:內建 HTTP 快取、資產壓縮與格式轉換,以及因為節點眾多而自帶的容錯與抗 DDoS 能力——這三個附帶效果會分別在後面談可擴展性、可用性與資安時被再次引用。限制是它只服務靜態內容,會動的部分要靠別的手段。

相關術語: edge location (由它組成)、network latency (解決)

出處:第 10 段「網路延遲與 CDN(scale level 1)」

edge location

邊緣節點

CDN 部署在靠近使用者的機房,存放資產副本或執行程式。

「邊緣」指的是網路的邊緣,也就是離終端使用者最近、離資料中心最遠的那一圈。同一組節點後來會被拿來做三件事:放資產(CDN)、跑程式(邊緣函式)、放唯讀資料副本,這也是下一段架構演進的主軸。

相關術語: CDN (組成單位)

出處:第 10 段「網路延遲與 CDN(scale level 1)」

TLS

傳輸層安全協定

在 TCP 之上加密與驗證連線的協定,HTTPS 就是 HTTP 跑在 TLS 上。

建立加密連線需要交握,而交握要來回,所以它是延遲的一部分。版本差異很大:TLS 1.2 需要兩次來回,TLS 1.3 只要一次、續連可 0-RTT。實務上減少交握成本的手段包括連線重用(HTTP/2、HTTP/3 的多工)與由 CDN 在邊緣終止 TLS——後者等於把交握的距離也縮短了。

相關術語: network latency (貢獻來源)

出處:第 10 段「網路延遲與 CDN(scale level 1)」

見仁見智 22:32
「when it comes to TCP plus TLS that's HTTPS you need at least four round trips」
這是 TLS 1.2 時代的數字。TLS 1.3(RFC 8446,2018)把交握壓到一次來回,續連可用 0-RTT;TCP 本身是一次來回即可送出資料。因此現代 HTTPS 建連約兩次來回,換算約 300 毫秒而非影片說的 600 毫秒;走 HTTP/3(QUIC)時傳輸層與加密交握合併,還會更短。結論(距離造成的延遲要靠縮短距離解決)不受影響,但數字別直接背去面試。
依據: RFC 8446(TLS 1.3, 2018)1-RTT handshake / 0-RTT resumption;RFC 9000(QUIC, 2021)
留給下一段 靜態資產的延遲解掉了,但畫面上會動的那一半還是得回伺服器。下一段處理動態內容的效能。

11. 從白畫面到邊緣運算(scale level 3) 24:28–29:16

動態內容用 React/Vue/Angular 這類框架時,使用者先拿到空 HTML,下載 JS、初次渲染、抓資料、再渲染,中間就是白畫面。SSR 讓伺服器先取資料並預渲染 HTML,使用者立刻看到內容,再靠 rehydrate 補上互動性。但 SSR 又把延遲問題請回來了——每次動態路徑都要回伺服器。於是把渲染搬到 edge functions(跑 Node 之類的執行環境、部署在離使用者近的節點),再把資料庫的唯讀副本也推到邊緣,靜態資產、運算、資料三者都貼近使用者。代價由 CAP 定理說明:既然要 partition tolerance,就得在一致性上讓步,唯讀副本同步有延遲;金融不能接受,社群可以。這就是 scale level 3。

CSR 的時間軸:空 HTML → 下載 JS → 渲染 → 抓資料 → 再渲染,白畫面的成因
25:00 · CSR 的時間軸:空 HTML → 下載 JS → 渲染 → 抓資料 → 再渲染,白畫面的成因
SSR 流程圖,對照上一張看差別
25:45 · SSR 流程圖,對照上一張看差別
edge functions 分散運算的示意圖
26:40 · edge functions 分散運算的示意圖
靜態資產+運算+唯讀資料庫全部推到邊緣的完整圖
27:35 · 靜態資產+運算+唯讀資料庫全部推到邊緣的完整圖
scale level 3 架構圖:CDN + 邊緣運算 + 分散式資料庫
29:05 · scale level 3 架構圖:CDN + 邊緣運算 + 分散式資料庫
承上 上一段用 CDN 解掉了靜態資產的延遲,但留下一個缺口:會動的那一半還是得回伺服器。這一段就從那一半開始。

推理因為動態畫面需要框架來管狀態與互動,作者先把純客戶端渲染的成本攤開:使用者拿到的是一份幾乎空的 HTML,只有一個掛載用的 div,接著下載 JavaScript、初次渲染、抓資料、再渲染,中間就是白畫面,使用者可能以為網站壞了而離開。第一層解法是 SSR:伺服器先取資料、預先渲染好 HTML 送出,使用者立刻看到內容,再由 hydration 把互動補上。但 SSR 又把上一段的延遲問題請回來了,因為每個動態路徑都要回源站。第二層解法是把渲染搬到邊緣函式——同樣的程式碼部署在離使用者近的節點。可是邊緣函式仍要回中央資料庫取資料,於是第三層是把資料庫的唯讀副本也推到邊緣。三樣東西(資產、運算、資料)都貼近使用者後,作者用 CAP 定理標出代價:副本同步有延遲,資料可能不是最新的,金融場景不能接受,社群場景可以。這一整套就是 Level 3。

AI 補充這一段其實是同一招用了三次:把東西搬近使用者。理解它的關鍵是看每一次搬完之後「還剩哪一段距離沒被解決」——搬完資產剩渲染,搬完渲染剩取資料,搬完資料才收斂。這個「找出剩下那段最長的路」的習慣,比記住 SSR 或 edge function 的定義更有用。要補的是 hydration 的代價:預渲染的 HTML 讓使用者「看得到」,但在 JavaScript 下載並接手之前是「按不動」的,這段空窗會直接反映在第 9 段的 INP 上,也是後來 streaming SSR、islands、React Server Components 這些做法想縮短的部分。至於 CAP,影片的表述繞了一圈,正確的說法是:網路分區發生時,你只能在一致性與可用性之間挑一個;唯讀副本這個設計選的是可用性,換來的是最終一致性。

術語:server-side renderingedge computing

client-side rendering

客戶端渲染

伺服器只送出近乎空白的 HTML,畫面完全由瀏覽器執行 JavaScript 產生。

縮寫 CSR。它的優點是伺服器負擔小、部署簡單,之後的導航也很快;缺點是第一次載入的路徑最長——下載 JS、執行、抓資料、再渲染,全部發生在使用者面前。對登入後的後台系統影響不大,對要被爬蟲讀到、或使用者跳出率敏感的頁面就很傷。

相關術語: white screen of death (造成)、server-side rendering (對照組)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

white screen of death

白畫面

JavaScript 尚未完成執行前,使用者只看得到一片空白的期間。

它之所以嚴重不只是難看,而是使用者無法分辨「還在載入」與「壞掉了」。骨架畫面能緩解感受,但無法縮短實際時間;真正縮短它的方式是讓伺服器或邊緣先送出有內容的 HTML。

相關術語: client-side rendering (症狀)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

server-side rendering

伺服器端渲染

伺服器先取好資料並產生完整 HTML 再送給瀏覽器,使用者立刻看得到內容。

縮寫 SSR。它把渲染工作從使用者的裝置搬到伺服器,代價是每個動態請求都要一次伺服器來回,而且伺服器要為每個請求付出渲染成本。它解的是「看得到」的時間,不是「按得動」的時間——後者取決於 hydration。

相關術語: hydration (後續步驟)、edge computing (延伸解法)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

hydration

水合

在預渲染好的 HTML 上執行框架程式碼、掛上事件處理,讓靜態畫面變成可互動的應用。

水合前的頁面看得到但按不動,這段空窗會被 INP 量到。它的成本與元件樹大小成正比,所以大型頁面常見的最佳化是分段水合、延後非首屏元件,或改用只在需要處送 JavaScript 的架構(islands、React Server Components)。

相關術語: server-side rendering (配套)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

edge computing

邊緣運算

把程式碼部署到靠近使用者的邊緣節點執行,而不是集中在單一資料中心。

在前端語境裡通常指邊緣函式:短生命週期、無狀態、被請求觸發。它沿用 CDN 的節點分布,但送的不是檔案而是運算結果,所以能讓 SSR 也享有就近的好處。限制是執行環境通常受限(記憶體小、不一定有完整 Node API),且離資料庫更遠——這正是下一步要推唯讀副本的原因。

相關術語: edge location (部署於)、read replica (需要搭配)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

read replica

唯讀副本

主資料庫的唯讀複本,部署在靠近使用者或運算節點的位置分擔讀取。

寫入仍然只發生在主庫,複製到副本需要時間,所以剛寫入的資料可能還讀不到(讀寫不一致)。常見的緩解是把「剛寫完馬上要讀」的路徑導回主庫。它同時服務兩個目的:降延遲,以及分散讀取壓力,因此在效能與可擴展性兩章都會出現。

相關術語: CAP theorem (受其約束)、edge computing (搭配)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

CAP theorem

CAP 定理

分散式系統在網路分區發生時,一致性與可用性只能擇一保證。

常被簡化成「三選二」,但分區容忍(P)不是選項而是前提——只要跨機器就有網路,就會有分區。所以真正的選擇是:分區時要繼續服務可能過期的資料(選 A),還是拒絕服務以保證正確(選 C)。平時沒有分區時的取捨則是延遲與一致性,這個補充版本叫 PACELC。判準永遠是業務:金融偏 C,內容與社群偏 A。

相關術語: read replica (取捨具現)

出處:第 11 段「從白畫面到邊緣運算(scale level 3)」

見仁見智 28:19
「because we have the partitioning guarantee, we'll use the consistency guarantee」
這句把 CAP 的取捨講反了,也和他自己下一句「資料可能不一致」矛盾。CAP 的正確讀法是:分散式系統必須容忍網路分區(P 不是可以放棄的選項),因此在分區發生時只能在一致性(C)與可用性(A)之間二選一。地理分散的唯讀副本選的是可用性,代價是最終一致性。另外 CAP 只描述分區期間的行為,平時的取捨其實是延遲與一致性(PACELC)。
依據: Gilbert & Lynch 對 CAP 的形式化證明(2002);Abadi 的 PACELC(2012)
留給下一段 效能這條線走完了,但整套架構的壓力全落在源站上。下一段換一個角度處理可擴展性:與其把請求送得更快,不如讓請求根本不發生。

12. 用快取消除請求 29:16–31:40

可擴展性是「使用者變多而效能不掉、最好連程式都不用改」。作者主張最好的擴展手段是先消除請求,判準是問「哪些資料讀遠多於寫」。商品圖片與標題讀很多寫很少,適合快取;價格與到貨時間則讀寫都頻繁,不適合。CDN 本身就實作了 HTTP 快取,越不常變的資產可以設越積極的快取策略;此外 CDN 還順手做資產最佳化——壓縮通常省下約 25% 傳輸量、圖片轉成 WebP、甚至 JS minification。

UI 上逐塊標示「讀多寫少 vs 讀寫皆頻繁」的分析圖,快取決策的依據
30:00 · UI 上逐塊標示「讀多寫少 vs 讀寫皆頻繁」的分析圖,快取決策的依據
CDN 的資產最佳化清單:壓縮、WebP、minification
31:15 · CDN 的資產最佳化清單:壓縮、WebP、minification
承上 上一段把資產、運算與資料都推到邊緣,但也讓源站承受了整套架構的壓力。這一段換一個思路:讓請求根本不要發生。

推理因為可擴展性的定義是「使用者變多而效能不掉、最好連程式都不用改」,作者主張最有效的擴展是先消除請求,而判斷哪些請求可以消除的問題只有一個:哪些資料讀遠多於寫?回到商品列表頁逐塊看——商品圖片與標題被讀上百萬次卻很少變動,適合快取;價格與到貨時間則讀寫都頻繁,不能這樣處理。接著他指出 CDN 本身就實作了 HTTP 快取,資產送到客戶端時就帶著保存指示,越不常變的東西可以設越積極的策略。他順帶補上 CDN 的另一項紅利:資產最佳化——壓縮通常省下約 25% 傳輸量、圖片轉成 WebP、甚至做 JS minification。

AI 補充「讀寫比」這個判準其實是第 6 段拆實體那條判準的回音:當時把價格、評分、到貨時間從 product 拆出去,理由是它們的變動頻率不同;現在同一份資訊直接決定了誰可以被快取多久。這說明資料建模不是純學術動作,它會一路影響到快取策略與請求量。要補的是快取真正的難題不在設定,而在失效:積極的策略讓過期資料活得更久,所以實務上會把「內容變了就換檔名」(雜湊檔名+長期快取)當成預設,而不是靠縮短快取時間。壓縮那個 25% 也視內容而定——文字類資產壓縮率遠高於此,已經壓過的圖片則幾乎壓不動。

HTTP caching

HTTP 快取

伺服器透過回應標頭告訴客戶端或中介節點,這份資源可以重複使用多久。

主要靠 Cache-Control 決定新鮮期,靠 ETag 或 Last-Modified 做過期後的重新驗證(沒變就回 304,不重傳內容)。前端最常見的組合是:帶雜湊檔名的建置產物設超長快取加 immutable,HTML 本身設不快取或極短快取,讓新版本能立刻生效。

相關術語: CDN (內建於)、asset optimisation (並列紅利)

出處:第 12 段「用快取消除請求」

asset optimisation

資產最佳化

在傳送前對靜態資產做壓縮、格式轉換與精簡,以減少傳輸量。

包含三類手段:傳輸壓縮(gzip、Brotli)、格式轉換(圖片轉 WebP 或 AVIF、依裝置寬度給不同尺寸)、以及程式碼精簡(minification、tree shaking)。前兩類可以由 CDN 在邊緣自動完成,第三類通常在建置階段完成。對第 8 段算出的行動族群來說,這是省流量最直接的一刀。

相關術語: minification (包含)

出處:第 12 段「用快取消除請求」

minification

程式碼精簡

移除程式碼中的空白、註解並縮短變數名稱,在不改變行為的前提下縮小檔案。

它縮小的是檔案大小,不是執行成本——JavaScript 下載後仍要解析與執行,這部分要靠減少程式碼量(拆包、延後載入)才會變快。與壓縮是互補的兩步:先精簡再壓縮,效果最好。

相關術語: asset optimisation (屬於)

出處:第 12 段「用快取消除請求」

留給下一段 能省的請求省完了,剩下的請求還是要打到後端,而後端已經是一堆微服務。下一段處理那些真的躲不掉的請求。

13. API Gateway 與 BFF 31:40–34:34

壓力全落在伺服器上,而後端多半已切成微服務。第一步加 API Gateway:它是反向代理,把 HTTPS、快取、授權這類重複工作集中做一次,對內轉成 HTTP 讓服務間通訊更快。第二步加 BFF(backend for frontend):一個由前端團隊擁有的中介層,按畫面需要的形狀組資料,背後去打各微服務,等於實作 facade pattern。好處是前端不必等微服務排期就能出功能,還能一個 client 一個 BFF(桌機一個、行動一個),這也是前端工程師被期待要有全端知識的原因。

加上 API Gateway 前後的架構對照
32:30 · 加上 API Gateway 前後的架構對照
BFF 把多個微服務組成單一視圖資料的示意圖
33:30 · BFF 把多個微服務組成單一視圖資料的示意圖
每個 client 各一個 BFF 的變體,說明它是組織選擇
34:20 · 每個 client 各一個 BFF 的變體,說明它是組織選擇
承上 上一段消除了能省的請求,但躲不掉的那些仍要打到已經切成微服務的後端。這一段開始整理後端的入口。

推理因為畫面上每個區塊都要向不同的微服務要資料,作者先加一層 API Gateway:它是反向代理,把 HTTPS、快取、授權這類每個服務都要做的重複工作集中做一次,對內轉成一般 HTTP,讓服務之間的通訊更輕。接著他加第二層 BFF:一個按畫面需要的形狀來組資料的中介層,前端只跟它說「這個畫面要這些東西」,由它去打各個微服務再拼起來,也就是 facade pattern。BFF 的關鍵不在技術而在歸屬——它由前端團隊擁有,所以出功能不必等微服務排期;而且可以一個 client 一套(桌機 BFF、行動 BFF),互不干擾。作者順勢點出這就是前端工程師被期待要有全端知識的原因。

AI 補充這兩層常被混為一談,但它們解的問題不同:API Gateway 解的是橫切關注點(每個服務都要做的事只做一次),BFF 解的是形狀不匹配(後端按領域切、畫面按視圖切)。判斷你需要哪一個,就看你的痛點是「重複實作」還是「前端要打很多支再拼」。BFF 的代價也值得先想清楚:它是一個必須部署、監控、擴展的服務,且每多一個 client 就多一份要維護的程式;當畫面差異不大時,一個 BFF 加參數往往比兩個 BFF 划算。另外 BFF 由前端團隊擁有這件事,其實已經是下一個章節(可維護性與康威定律)的伏筆——它是用組織邊界來換交付速度。

microservices

微服務

把後端拆成多個各自負責一塊業務、可獨立部署的小服務。

它讓各團隊能獨立發版,代價是每個跨服務的畫面都要多次網路呼叫,而且需要一套統一的入口與治理。對前端來說最直接的影響是:資料來源從一個變成很多個,這正是 API Gateway 與 BFF 存在的理由。

相關術語: API gateway (共同入口)、backend for frontend (被它彙整)

出處:第 13 段「API Gateway 與 BFF」

API gateway

API 閘道

所有外部請求的統一入口,集中處理認證、加密、限流、快取等共通事務。

它把橫切關注點從每個服務裡抽出來只做一次:對外終止 HTTPS、驗 token、擋超量請求,對內轉發較輕量的請求。它不理解業務語意,只做轉發與治理——需要理解「這個畫面要什麼」的那一層是 BFF。代價是它本身成為必經之路,因此也是需要被冗餘保護的關鍵元件。

相關術語: reverse proxy (是一種)、backend for frontend (常置於其後)

出處:第 13 段「API Gateway 與 BFF」

reverse proxy

反向代理

代表後端接收請求再轉發的中介伺服器,對客戶端而言它就是伺服器。

與正向代理相反:正向代理代表客戶端出去,反向代理代表伺服器對外。它是本片後半段好幾個元件的共同底層形態——API Gateway、BFF、負載平衡器都是反向代理,差別只在它們額外做了什麼。

相關術語: API gateway (應用)

出處:第 13 段「API Gateway 與 BFF」

backend for frontend

前端專屬後端

為特定前端客戶端量身打造的中介層,按畫面需要的形狀彙整多個服務的資料。

縮寫 BFF。它的定義性特徵是歸屬:由前端團隊擁有與部署,所以介面可以隨畫面調整而不必協調後端。典型做法是一個 client 一個 BFF(桌機、行動、電視),避免用同一份介面服務需求差很大的裝置。代價是多一個要維運的服務,以及可能出現的邏輯重複。

相關術語: facade pattern (實作)、under-fetching (緩解)

出處:第 13 段「API Gateway 與 BFF」

facade pattern

外觀模式

在一組複雜子系統前面放一個簡化的統一介面,讓呼叫方只面對一個入口。

重點是它不消除複雜度,只是把複雜度收在一側。BFF 就是這個模式在系統層級的實作:微服務的拆分方式仍然複雜,但前端只看得到一個為它設計的介面。用它的前提是那個介面確實比較穩定——如果外觀跟著子系統一起變,就沒有得到任何隔離。

相關術語: backend for frontend (被它採用)

出處:第 13 段「API Gateway 與 BFF」

留給下一段 資料的入口整理好了,但第 6 段那個「一次瀏覽打五支 API」的問題還沒真正解掉,而且流量現在全壓在 BFF 上。下一段同時處理這兩件事。

14. GraphQL 與水平擴展(scale level 4) 34:34–36:58

在 BFF 上加 GraphQL,就能用一次查詢取多個資源,直接解掉開頭那個 under-fetching:原本一次瀏覽五支 API,現在變成一次查詢,由 BFF 的 resolver 分頭去取再組成單一 JSON。附帶好處是前端能只要它需要的欄位,對流量敏感的行動使用者特別有利。流量現在集中在 BFF,所以用水平擴展:加負載平衡器,依 round robin 或最少連線數把流量分給多個相同實例。這就是 scale level 4。

GraphQL 單一查詢取代五次 REST 呼叫的對照圖
35:20 · GraphQL 單一查詢取代五次 REST 呼叫的對照圖
scale level 4 架構圖:CDN + API Gateway + BFF + 負載平衡
36:40 · scale level 4 架構圖:CDN + API Gateway + BFF + 負載平衡
承上 上一段留下兩個未完成的問題:第 6 段的 under-fetching 還沒解,流量又全壓在 BFF 上。這一段一次處理。

推理因為 BFF 已經是「按畫面組資料」的位置,作者在它上面加 GraphQL:前端用一次查詢就取到多個資源,由 BFF 的 resolver 分頭去打各微服務再組成單一 JSON 回傳,原本一次瀏覽五支 API 變成一次查詢。附帶的好處是前端可以只要它需要的欄位,不多不少,對流量敏感的行動使用者特別有價值。至於流量集中在 BFF 的問題,他用最直接的水平擴展處理:加一台負載平衡器,依 round robin 或最少活躍連線數把流量分給多個相同的 BFF 實例。這一套就是 Level 4。

AI 補充GraphQL 解的是「形狀」而不是「速度」——它把多次來回換成一次來回,但後端該打的服務一支都沒少,只是移到 BFF 內部並行處理。也因此它引進了自己的新問題:查詢複雜度需要限制(否則一個惡意查詢可以打爆後端)、快取比 REST 難(不再是一個 URL 對應一份資源,要靠正規化的客戶端快取或持久化查詢)。這些是面試中提到 GraphQL 時值得主動說出來的取捨。水平擴展這邊也有一個前提沒被說破:實例必須是無狀態的,同一個使用者的下一個請求才能被送到任何一台;session 一旦存在實例記憶體裡,加機器就會出錯。

術語:over-fetching

GraphQL

GraphQL 查詢語言

讓客戶端用一次查詢,依 schema 指定需要哪些資源與欄位的 API 技術。

它同時對付 under-fetching(一次查完)與 over-fetching(只要需要的欄位)。代價是快取與治理變難:REST 靠 URL 就能在 CDN 層快取,GraphQL 通常所有查詢打同一個端點,得改用持久化查詢或客戶端正規化快取;另外需要限制查詢深度與複雜度以防濫用。它最適合放在 BFF 這種「多來源彙整」的位置。

相關術語: resolver (由它執行)、over-fetching (解決)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

resolver

解析器

GraphQL schema 中每個欄位對應的取值函式,負責去實際的資料來源拿資料。

一個查詢會展開成一棵 resolver 呼叫樹,因此天然容易出現 N+1 問題(列表中每一筆各打一次下游)。標準對策是批次載入與快取(DataLoader 這類工具)。理解 resolver 也就理解了為什麼 GraphQL 不會自動變快——它只是把多次來回搬到伺服器端執行。

相關術語: GraphQL (組成)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

over-fetching

取得過多

一次請求拿回超出畫面所需的欄位或資料量。

它是 under-fetching 的鏡像問題:為了讓一支端點服務多個畫面,回應會涵蓋所有情境需要的欄位,結果每個畫面都拿到用不到的資料。在行動網路上這是實際成本(流量、解析時間、記憶體)。REST 的緩解是稀疏欄位參數,GraphQL 則是由查詢直接指定。

相關術語: under-fetching (鏡像問題)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

horizontal scaling

水平擴展

以增加相同實例的數量來承載更多流量,而不是把單一機器換得更強。

相對於垂直擴展(換更大的機器)。它的前提是實例無狀態且可任意替換,好處是幾乎沒有上限而且天然帶來容錯(壞一台還有其他台)。代價是需要一個分流的角色,也就是負載平衡器,而那個角色本身又變成必須被保護的關鍵點。

相關術語: load balancer (需要)、scalability (手段)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

load balancer

負載平衡器

依演算法把進來的流量分配給多個相同實例的元件。

常見演算法是 round robin(輪流)與 least active connections(挑目前最閒的),另有依來源雜湊做黏著性的做法。它通常還負責健康檢查——把流量從沒回應的實例移走,這使它同時是可擴展性與可用性的元件。但它自己若只有一台,就是典型的單點故障。

相關術語: round robin (演算法)、horizontal scaling (使其可行)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

round robin

輪詢

把請求依序輪流分配給每個實例的分流演算法。

最簡單也最公平的分法,前提是每個請求成本相近、每台機器規格相同。當請求耗時差異大時,最少活躍連線數通常表現更好;當實例規格不同時,可以用加權輪詢。

相關術語: load balancer (用於)

出處:第 14 段「GraphQL 與水平擴展(scale level 4)」

留給下一段 到這裡效能與可擴展性都有解了,但整個前端仍然是一整塊、由一個大團隊維護。下一段換一個維度:可維護性。

15. 康威定律與微前端(scale level 5) 36:58–39:24

可維護性是「擴充系統有多容易」。就算後端已微服務化,前端仍是單體,而康威定律說組織設計出的系統會複製自己的溝通結構;團隊一大,溝通線就爆炸(3 人 3 條、14 人 91 條),作者舉了一個 45 人開 1.5 小時 daily standup 的真實案例。依貝佐斯的兩個披薩原則要拆團隊,而依康威定律,拆團隊就得拆系統:把前端單體拆成微前端——各自獨立、各自網域、各自發版,由一個 shell 在執行期組起來給使用者看。這是 scale level 5。

3 人 vs 14 人的溝通線條數對比圖,讓「溝通成本爆炸」變成可看見的數字
37:35 · 3 人 vs 14 人的溝通線條數對比圖,讓「溝通成本爆炸」變成可看見的數字
前端單體被拆成多個微前端、由 shell 組裝的架構圖
39:05 · 前端單體被拆成多個微前端、由 shell 組裝的架構圖
承上 上一段把效能與可擴展性都補齊了,但也點出前端仍是一整塊、由一個大團隊維護。這一段處理這個維度。

推理因為可維護性談的是擴充系統的容易程度,作者先搬出康威定律:組織設計出的系統會複製自己的溝通結構。接著他把「團隊太大」量化成溝通線的數量——3 人 3 條、14 人 91 條,畫面上那張圖讓成長速度一目瞭然——並補上一個真實案例:某公司 45 人共用一個單體應用,每天開 1.5 小時的站立會議,九成內容與你無關。既然貝佐斯的兩個披薩原則說團隊該拆,而康威定律說系統會長成團隊的樣子,那要拆團隊就得先拆系統。於是前端單體被拆成微前端:各自獨立、部署在不同網域、各自發版,由一個 shell 在執行期把它們組起來呈現給使用者。這就是 Level 5。

AI 補充這段的推理鏈值得單獨記:溝通成本隨人數呈平方成長 → 大團隊必然低效 → 拆團隊 → 依康威定律必須同時拆系統 → 微前端。倒過來看也成立,而且更常用:如果你的系統邊界和團隊邊界對不上,痛苦會出現在每次發版的協調上。微前端的代價作者沒展開,但面試中值得主動提:重複的相依套件會讓總下載量變大、跨應用的路由與狀態共享變複雜、樣式與版本容易失控。這也直接說明了為什麼下一段必須補兩樣東西——沒有那兩樣,微前端會退化成一堆看起來不像同一個網站的應用。

術語:two-pizza teamshell application

Conway's law

康威定律

組織產出的系統結構,會複製該組織的溝通結構。

1967 年由 Melvin Conway 提出,原本是觀察而非規範。實務上的用法有兩種:診斷(系統為什麼長成這樣?因為團隊就長這樣)與設計(想要什麼架構,就先把團隊照那個形狀組起來,稱為 inverse Conway manoeuvre)。它也解釋了為什麼純技術手段解不了架構問題——邊界不改組織,就會被組織改回去。

相關術語: micro frontend (推導出)、two-pizza team (同一組主張)

出處:第 15 段「康威定律與微前端(scale level 5)」

two-pizza team

兩個披薩團隊

貝佐斯的經驗法則:一個團隊的人數要少到兩個披薩就能餵飽。

數字不重要,背後的量化理由才重要——溝通線數量是 n(n-1)/2,隨人數呈平方成長,所以 14 人的協調成本是 5 人的九倍以上。它與康威定律搭配使用:先用它決定團隊多大,再用康威定律推出系統該切成幾塊。

相關術語: Conway's law (搭配)

出處:第 15 段「康威定律與微前端(scale level 5)」

micro frontend

微前端

把前端拆成多個可獨立開發、部署、發版的應用,在執行期組合成單一介面。

組合方式可以是執行期(Module Federation、iframe、Web Components)或建置期。它換來的是團隊自主與獨立發版,付出的是重複相依、跨應用狀態與路由的複雜度、以及視覺一致性的風險。判斷值不值得的關鍵不是程式碼規模,而是團隊數量——只有一個團隊時,微前端幾乎只有成本。

相關術語: shell application (需要)、design system (必要補償)

出處:第 15 段「康威定律與微前端(scale level 5)」

shell application

殼層應用

負責在執行期載入各個微前端、處理共用路由與版面的外層容器。

它是使用者實際打開的那個應用,決定哪些微前端在什麼路徑下被掛載,並提供共用的頂層版面與跨應用通訊管道。它的風險是容易長成新的單體——共用的東西越放越多,各團隊又回到要協調同一份程式碼的狀態。

相關術語: micro frontend (承載)

出處:第 15 段「康威定律與微前端(scale level 5)」

留給下一段 系統拆開了,團隊也小了,但立刻出現兩個新問題:各自為政會長得不一樣,換團隊的人也會迷路。下一段補這兩個洞。

16. Design system 與 monorepo 39:24–41:47

微前端拆開後產生兩個新問題。第一是視覺不一致:解法是 design system——一套內部共用的 UI 元件庫,通常以 npm 套件發佈,目標是加快開發(不必每個團隊重刻表單和日期選擇器)與跨微前端的視覺一致。第二是程式品質與人員流動:各自的 repo 會各有 lint 規則、TypeScript 設定、測試環境與套件版本,於是全部收進 monorepo——共用建置系統、共用品質工具、共用套件,甚至共用部署流程(各應用產出 docker image 再由 monorepo 工具一起部署)。這是 scale level 7,擴展的是組織。

design system 作為共用元件庫餵給各微前端的關係圖
40:00 · design system 作為共用元件庫餵給各微前端的關係圖
多 repo 各自設定 vs monorepo 共用工具鏈的對照
41:10 · 多 repo 各自設定 vs monorepo 共用工具鏈的對照
承上 上一段拆出微前端後留下兩個洞:各應用會長得不一樣,換團隊的人會迷路。這一段分別補上。

推理因為視覺一致性沒了,作者先補 design system:一套內部共用的 UI 元件庫,通常以 npm 套件發佈給所有微前端使用。它的兩個目的很明確——加快開發(不必每個團隊各自重刻表單、日期選擇器)與跨應用的視覺一致。第二個洞是程式品質與人員流動:各自的 repo 會各有 lint 規則、TypeScript 設定、測試環境與套件版本,於是他把所有應用收進同一個 monorepo,共用建置系統、共用品質工具、共用套件,甚至共用部署流程——各應用產出 docker image,再由 monorepo 的工具一起部署到各自的網域。附帶效果是透明度:任何人都能讀到公司幾乎所有原始碼。這一層他稱為 Level 7,擴展的對象是組織。

AI 補充這兩樣東西要一起看,才看得出它們在補同一件事:微前端把系統拆開換取自主,而 design system 與 monorepo 把「該一致的部分」重新收攏,避免自主變成失控。分辨兩者的分工很有用——design system 統一的是使用者看到的東西,monorepo 統一的是工程師碰到的東西。實務上兩者都有代價:design system 需要專責維護,否則會變成沒人敢改的化石;monorepo 需要投資工具(受影響範圍偵測、遠端建置快取),否則 CI 時間會隨 repo 成長線性惡化。要注意的是這裡的 scale level 編號不連續(作者從 Level 5 直接跳到 Level 7),記順序就好。

design system

設計系統

一套內部共用的 UI 元件與設計規範,讓不同團隊做出來的介面看起來像同一個產品。

它不只是元件庫,還包含設計代幣(顏色、間距、字級)、無障礙預設與使用指引——後者讓語意化 HTML 與鍵盤操作變成預設而非額外工作。成功的關鍵是治理:誰能新增元件、破壞性變更怎麼發版。失敗的典型是版本落後又沒人維護,各團隊開始複製貼上自己改。

相關術語: micro frontend (補償其代價)、monorepo (常同處)

出處:第 16 段「Design system 與 monorepo」

monorepo

單一儲存庫

把多個應用與套件放在同一個版本庫,共用建置、品質工具與相依管理。

它與單體是兩件事:monorepo 講的是程式碼放哪,單體講的是怎麼部署;微前端+monorepo 是常見且合理的組合。好處是跨專案的原子提交、統一工具鏈、以及降低換團隊的學習成本;代價是需要專門的工具處理受影響範圍偵測與建置快取(Nx、Turborepo、Bazel 之類),否則 CI 會越來越慢。

相關術語: design system (常一起放)

出處:第 16 段「Design system 與 monorepo」

見仁見智 41:47
「that would be our scale level number seven where we scale our organization」
這裡的編號跳號了。影片實際出現過的階層是 Level 0(純 client-server)、Level 1(加 CDN)、Level 3(邊緣運算+分散式資料庫)、Level 4(API Gateway+BFF+負載平衡)、Level 5(微前端),接著直接跳到 Level 7,中間的 2 與 6 沒有對應的畫面。這是自創的教學編號而非業界標準,記住演進順序即可,別把數字當共通語言用在面試裡。
依據: 影片內出現的階層標題投影片(0:45、12:58、24:05、29:05、36:45、39:00)
留給下一段 效能、可擴展性、可維護性都有了,但整張架構圖裡還藏著幾個「壞掉就全倒」的位置。下一段檢查可用性。

17. 可用性、單點故障與 active-passive 41:47–43:42

可用性靠的是分布模式,而 CDN、負載平衡器、唯讀副本這些為了擴展而加的東西,同時也提高了可用性:任一 edge location、任一實例、任一副本掛掉都能把流量導去其他健康的節點。但負載平衡器與主資料庫本身變成單點故障——一掛全系統倒(DNS 伺服器也是典型例子)。作者補了一個 active-passive 模式:兩台負載平衡器,一台接流量、一台待命,主的掛了立刻切過去。前端工程師不需要會實作,但要有這層心智模型。

active-passive 雙負載平衡器的切換示意圖
43:20 · active-passive 雙負載平衡器的切換示意圖
承上 上一段補完了組織層面的擴展,也留下一個問題:這張越來越大的架構圖裡,哪些位置壞掉會讓全部停擺?

推理因為可用性靠的是分布,作者先指出一個順帶的好消息:前面為了效能與擴展加進來的元件本來就有冗餘——CDN 的某個 edge location 掛了可以改導其他節點,負載平衡器後面的實例掛了可以只送給健康的,唯讀副本掛了還有其他副本。但接著他把壞消息點名:負載平衡器與主資料庫本身只有一份,它們是單點故障,DNS 伺服器也是同類。解法是他當作彩蛋補上的 active-passive 模式——放兩台負載平衡器,一台接流量、一台待命,主的失效就立刻切過去。他也提醒前端工程師不需要會實作,但要有這層心智模型。

AI 補充這段的實用價值在於一個檢查動作:對著自己畫的架構圖,逐個元件問「這個只有一份嗎?」凡是只有一份的,就是可用性的天花板。要補的是 active-passive 不是免費的——待命那台平常閒置卻要付費,而且切換需要偵測失效與轉移流量(通常靠健康檢查加虛擬 IP 或 DNS 切換),這段空窗就是實際的停機時間。另一個常被忽略的是:待命節點必須被定期演練,否則真的要切的時候往往才發現它的設定早就過期了。

術語:active-passive pattern

single point of failure

單點故障

系統中只有一份、一旦失效就會讓整體停擺的元件。

縮寫 SPOF。找它的方法很機械:對架構圖上每個方塊問「有幾份?」,答案是一份的就是候選。典型的隱形 SPOF 包括 DNS、憑證、單一雲端區域、以及只有一個人知道怎麼操作的部署流程。消除方式不外乎複製它,或準備一條可以立刻接手的備援路徑。

相關術語: active-passive pattern (由它解決)、fault tolerance (威脅)

出處:第 17 段「可用性、單點故障與 active-passive」

active-passive pattern

主備模式

同時準備兩份元件,一份接流量,另一份待命,主要那份失效時立即接手。

相對於 active-active(兩份同時分擔流量)。主備的優點是狀態同步簡單、行為好預測,缺點是待命資源平常閒置,而且切換有偵測與轉移的空窗。選哪一種取決於元件能不能同時多份運作:無狀態的服務通常直接做 active-active,有寫入權的主資料庫則多半是主備。

相關術語: single point of failure (對策)

出處:第 17 段「可用性、單點故障與 active-passive」

留給下一段 拓撲層面的問題到此收束。剩下兩個非功能需求靠的不是架構而是實作紀律——下一段處理無障礙與資安。

18. 無障礙與資安速查 43:42–46:07

無障礙的做法:一切用語意化 HTML(h1、list、footer 這類),實在做不到才用 aria 屬性,且應是例外不是常態;tab 順序要與畫面視覺順序一致;用 axe 這類外掛在開發階段就測。常見反例是 React 開發者習慣多包一層 div/span。資安則要能講清楚主要攻擊:中間人(用 HTTPS 加密)、XSS(不要執行使用者給的內容,別用 dangerouslySetInnerHTML)、CSRF(重要操作加二階段驗證)、SQL injection(後端用 ORM)、DDoS(流量過濾、Cloudflare 這類大網路、rate limiting)。

無障礙四條做法的清單
44:00 · 無障礙四條做法的清單
五種主要攻擊與各自對策的對照表,可直接當面試速查
45:00 · 五種主要攻擊與各自對策的對照表,可直接當面試速查
承上 上一段結束了架構拓撲的討論,並指出剩下兩項非功能需求靠實作紀律。這一段就把那兩份清單交出來。

推理因為無障礙的大部分收益來自預設值,作者的第一條就是盡量用語意化 HTML,這樣許多無障礙行為是免費的;真的做不到時才用 aria 屬性,而且應該是例外;tab 順序要與畫面的視覺順序一致(用語意化 HTML 通常自然成立);最後在開發階段就用 axe 這類工具測,而不是上線後才補。他點名最常見的反例是 React 開發者習慣多包一層 div 或 span。資安部分他採速查表的形式,要求你能講清楚主要攻擊與對策:中間人(全站 HTTPS)、XSS(不要把使用者內容當程式執行,別用 dangerouslySetInnerHTML)、CSRF(重要操作加第二因素)、SQL injection(後端用 ORM)、DDoS(流量過濾、Cloudflare 這類大型網路、rate limiting)。他也回頭補了一句:CDN 的節點分布本身就讓攻擊者很難打垮系統。

AI 補充這兩份清單看起來像背誦題,但有一條共同邏輯值得抓住:預設安全比事後檢查便宜。語意化 HTML 是無障礙的預設值,ORM 的參數化查詢是 SQL injection 的預設值,框架預設跳脫輸出是 XSS 的預設值——這些做法之所以有效,是因為它們讓「做對」比「做錯」更省事。要補兩點:第一,CSRF 的標準對策其實是 SameSite cookie 與 CSRF token,第二因素只適合真正高風險的操作,對每個寫入請求都要求二次驗證並不可行;第二,XSS 的防線除了不執行使用者內容,還包括 Content Security Policy,它是在你不小心漏掉時擋下來的第二層。無障礙的等級(A / AA / AAA)在第 7 段已經提過,這裡的四條做法就是把 AA 拿下來的最短路徑。

術語:man-in-the-middle attack

semantic HTML

語意化 HTML

用標籤本身的意義來標記內容,例如標題用 h1、清單用 ul、頁尾用 footer。

它的價值在於免費取得一整套行為:鍵盤可聚焦、螢幕閱讀器能報出角色、tab 順序自然正確、爬蟲讀得懂結構。用 div 加 onClick 模擬按鈕時,這些全都要自己重做一次(role、tabindex、鍵盤事件、焦點樣式),而且很少做全。這也是它同時服務無障礙與 SEO 兩個目標的原因。

相關術語: ARIA (退而求其次)、SEO (同時受益)

出處:第 18 段「無障礙與資安速查」

ARIA

無障礙富網際網路應用屬性

一組補充語意的 HTML 屬性,用來描述原生標籤表達不了的角色與狀態。

第一守則是「不要用 ARIA」——能用原生標籤就用原生標籤,因為 ARIA 只改變輔助技術聽到的描述,不會帶來任何行為(不會讓 div 變得可聚焦或能用 Enter 觸發)。用錯的 ARIA 比不用更糟,因為它會給出錯誤的承諾。適用場景是原生沒有對應元素的複合元件,例如頁籤、樹狀選單、即時通知區。

相關術語: semantic HTML (優先於它)

出處:第 18 段「無障礙與資安速查」

XSS

跨站腳本攻擊

攻擊者把腳本混進內容中,讓其他使用者的瀏覽器執行它。

全名 cross-site scripting。分成儲存型(存進資料庫再散播給所有讀者,例如惡意留言)、反射型(透過網址參數)與 DOM 型(前端把不受信任的值寫進 DOM)。防線有三層:輸出時跳脫(框架預設就會做)、絕不把使用者內容當 HTML 或程式碼插入(避免 dangerouslySetInnerHTML、innerHTML、eval),以及用 Content Security Policy 限制可執行的腳本來源。

相關術語: CSRF (並列攻擊)

出處:第 18 段「無障礙與資安速查」

CSRF

跨站請求偽造

誘使已登入的使用者在不知情下,對目標網站送出帶著自己憑證的請求。

全名 cross-site request forgery。關鍵在於瀏覽器會自動附帶 cookie,所以攻擊者不需要偷到憑證也能借用身分。現代標準對策是 SameSite cookie 屬性加上 CSRF token,並確保會改變狀態的操作一律不用 GET;影片提到的第二因素只適合真正高風險的動作(改密碼、轉帳)。

相關術語: XSS (並列攻擊)

出處:第 18 段「無障礙與資安速查」

SQL injection

SQL 注入

把 SQL 片段混進輸入欄位,使後端組出的查詢執行攻擊者的指令。

根因是把資料當成程式碼拼進字串。對策是參數化查詢——把值與語法分開送給資料庫,這也是 ORM 預設就安全的原因。前端無法防禦它(客戶端驗證可被繞過),但面試中要能說清楚它發生在哪一層、為什麼參數化有效。

相關術語: XSS (同類:資料當程式)

出處:第 18 段「無障礙與資安速查」

DDoS

分散式阻斷服務攻擊

用大量分散的來源同時湧入請求,耗盡目標的資源使其無法服務正常使用者。

全名 distributed denial of service。防禦靠的是規模與過濾:大型 CDN 的總容量遠大於多數攻擊者能買到的頻寬,再加上流量特徵過濾與 rate limiting。這也是第 10 段那個「把資產推到邊緣」的決定,在資安章節收到的第三份紅利。

相關術語: CDN (由它緩解)

出處:第 18 段「無障礙與資安速查」

man-in-the-middle attack

中間人攻擊

攻擊者在客戶端與伺服器之間竊聽或竄改往來的流量。

對策是全站 HTTPS,讓流量在傳輸中被加密與驗證。實務上還要加上 HSTS(強制瀏覽器只用 HTTPS 連線),否則第一次的 HTTP 請求仍可能被劫持並降級。這也是為什麼第 13 段的 API Gateway 常負責統一終止 HTTPS——加密要涵蓋所有對外服務才有意義。

相關術語: TLS (由它防禦)

出處:第 18 段「無障礙與資安速查」

留給下一段 六項非功能需求都處理完了。最後還有兩個常被追問的加分題——下一段收尾。

19. SEO 與前端可觀測性 46:07–48:25

兩個加分題。SEO:前面做的事幾乎全都順便幫到 SEO——SSR 交給爬蟲預渲染好的 HTML、語意化 HTML 讓頁面對爬蟲有意義、Core Web Vitals 高 Google 排名更好。可觀測性是團隊理解系統現況的能力:集中式的 log 與告警(Datadog)、真實使用者監控看實際 Core Web Vitals(Sentry)、產品分析做功能決策與 A/B 測試(Amplitude)、網站分析看轉換漏斗(Google Analytics)、以及處理使用者資料必備的 consent manager。最後把這些分析工具丟給 web worker 執行,主執行緒才不會被拖慢。

可觀測性工具的分類表:log/RUM/產品分析/網站分析/consent
47:00 · 可觀測性工具的分類表:log/RUM/產品分析/網站分析/consent
承上 上一段結束了六項非功能需求,並預告還有兩個常被追問的加分題。這一段把它們補完並收束全片。

推理因為前面的決策已經順帶解決了 SEO,作者只需要把連結指出來:SSR 交給爬蟲的是預先渲染好的 HTML,比空殼容易消化;語意化 HTML 讓頁面結構對爬蟲有意義;Core Web Vitals 高則直接影響 Google 排名。第二個加分題是可觀測性,也就是團隊理解系統現況的能力,他按用途分了五類工具:集中式的 log 與告警(Datadog)、真實使用者監控看實際的 Core Web Vitals(Sentry)、產品分析決定要擴充哪些功能與做 A/B 測試(Amplitude)、網站分析看廣告漏斗與轉換(Google Analytics)、以及處理使用者資料時必備的 consent manager。最後他補上一個效能上的收尾:把這些分析工具丟給 web worker 執行,主執行緒才不會被自己加的工具拖慢。

AI 補充SEO 這段其實驗證了全片的核心主張——好的非功能需求決策會互相加成,而不是彼此交換。同一個 SSR 決定同時買到了首屏速度、可被爬蟲索引與更好的排名;同一個語意化 HTML 決定同時買到了無障礙與 SEO。這也是面試中把「順帶解決了什麼」講出來的價值所在。可觀測性那五類工具的分野值得記牢,因為它們回答的問題完全不同:log 回答「壞了嗎」,RUM 回答「使用者實際體驗多快」,產品分析回答「他們在用什麼」,網站分析回答「他們從哪來、有沒有轉換」,consent manager 回答「我們有沒有權利收這些」。最後那個 web worker 的提醒是全片最後一個閉環:第 9 段說 INP 量的是主執行緒被塞住的程度,而分析工具正是塞住它的常見元兇。

SEO

搜尋引擎最佳化

讓頁面更容易被搜尋引擎正確索引並取得較好排名的做法。

對前端而言主要是三件事:內容要在 HTML 裡拿得到(SSR 或靜態生成)、結構要有語意(標題層級、地標元素、結構化資料)、體驗要快(Core Web Vitals 是排名訊號之一)。純客戶端渲染不是完全不能被索引,但取決於爬蟲願不願意執行你的 JavaScript 以及花多少預算,對電商這種靠自然流量的場景風險太高。

相關術語: server-side rendering (受益於)、semantic HTML (受益於)

出處:第 19 段「SEO 與前端可觀測性」

observability

可觀測性

從系統對外送出的資料,推斷它內部狀態的能力。

它比監控更廣:監控回答你事先想好的問題(CPU 超過八成了嗎),可觀測性要讓你回答事前沒想到的問題(為什麼只有某地區的 Android 使用者結帳失敗)。前端的特殊之處是執行環境不在你手上——瀏覽器、網路、裝置都由使用者決定,所以資料必須從真實使用者那裡收集。

相關術語: real user monitoring (包含)、consent manager (受其約束)

出處:第 19 段「SEO 與前端可觀測性」

real user monitoring

真實使用者監控

從真實使用者的瀏覽器收集效能與錯誤資料,而不是在實驗室環境模擬。

縮寫 RUM,相對於合成監控(固定環境定時跑測試)。兩者互補:合成監控適合在部署前擋住退步,RUM 才看得到真實裝置與網路的長尾——通常 p75 或 p95 遠比平均值有意義,因為體驗差的那群人正是會離開的人。第 9 段的 Core Web Vitals 就是靠 RUM 才拿得到真實數字。

相關術語: Core Web Vitals (量測)

出處:第 19 段「SEO 與前端可觀測性」

web worker

網頁工作執行緒

在主執行緒之外的背景執行緒中跑 JavaScript,避免阻塞畫面更新與互動。

它拿不到 DOM,因此適合純運算或 I/O 型的工作:分析事件的批次處理與上傳、大量資料的解析與排序、加解密。把第三方分析腳本移進 worker(例如透過 Partytown 這類方案)能直接改善 INP,因為主執行緒不再被它們的長任務佔住。

相關術語: INP (改善)

出處:第 19 段「SEO 與前端可觀測性」

consent manager

同意管理平台

在載入追蹤工具前取得並記錄使用者同意的機制。

GDPR 這類法規要求非必要的追蹤必須先取得同意,因此它必須真的控制腳本的載入時機,而不只是顯示一個橫幅。它同時是效能議題——同意橫幅通常是最早載入的第三方腳本之一,做不好會直接拖慢 LCP。

相關術語: observability (前置條件)

出處:第 19 段「SEO 與前端可觀測性」

留給下一段 總結收束。

4. 總結

作者的整條推理鏈是這樣接起來的:先主張面試要學的是可遷移的心智模型而非背範例,於是用飛機比喻把需求拆成功能與非功能兩類;功能需求導出低保真 UI 草稿,草稿上逐塊抽出必要狀態並用不可再簡測試驗收,狀態的位置則由「哪裡發生副作用」決定,得到 lifting state 的判準。狀態要打 API,於是把實體按變動頻率拆成五個 REST 資源,代價是一次瀏覽要打五支 API——under-fetching 就此登場,也宣告陽春 client-server 架構的極限。後半段改由非功能需求驅動:先把六項需求列成清單並示範該問哪些問題,再用信封背面估算把「每月 21.1 億次造訪」推成尖峰每小時 1.36 億次頁面瀏覽,證明單機不可能;接著用光速與來回次數證明延遲來自距離,導出 CDN(Level 1);動態內容再走一遍 CSR 白畫面 → SSR → 邊緣運算 → 分散式唯讀資料庫(Level 3),並以 CAP 標出一致性的代價。可擴展性則先用讀寫比決定哪些請求可以被快取消除,剩下的請求交給 API Gateway 收攏共通事務、BFF 按畫面組資料、GraphQL 把五次來回收成一次、負載平衡做水平擴展(Level 4)。最後換維度:康威定律說團隊結構決定系統結構,所以拆團隊要先拆系統 → 微前端(Level 5),再用 design system 補回視覺一致、monorepo 補回工具鏈一致(Level 7);收尾檢查單點故障與 active-passive,補上無障礙與資安的實作清單,並指出 SSR、語意化 HTML、Core Web Vitals 這些決策順帶把 SEO 也解決了。全片的隱含結論是:架構不是一次選好的,而是被一個個非功能需求逼出來的,面試要展示的正是這個被逼出來的過程。

勘誤總整理

確定錯誤/已過時見仁見智(取決於版本或情境)

段落原話(transcript 逐字)說明
5. 狀態的高度:lifting state
9:02
「make sure you start with your state being very global and then raise it as high as necessary but as low as possible」這句把方向講反了。同一段前面的原則是「as low as possible, as high as necessary」——從元件樹最低層開始放,只在有共用需求或副作用需要時才往上抬。照字面「start with your state being very global」做,會得到一份什麼都在頂層的狀態,正是這段要避免的結果。
依據: 同段 8:06 前後作者自己的表述:lifting state is a necessary evil, only if it's really necessary
10. 網路延遲與 CDN(scale level 1)
22:32
「when it comes to TCP plus TLS that's HTTPS you need at least four round trips」這是 TLS 1.2 時代的數字。TLS 1.3(RFC 8446,2018)把交握壓到一次來回,續連可用 0-RTT;TCP 本身是一次來回即可送出資料。因此現代 HTTPS 建連約兩次來回,換算約 300 毫秒而非影片說的 600 毫秒;走 HTTP/3(QUIC)時傳輸層與加密交握合併,還會更短。結論(距離造成的延遲要靠縮短距離解決)不受影響,但數字別直接背去面試。
依據: RFC 8446(TLS 1.3, 2018)1-RTT handshake / 0-RTT resumption;RFC 9000(QUIC, 2021)
11. 從白畫面到邊緣運算(scale level 3)
28:19
「because we have the partitioning guarantee, we'll use the consistency guarantee」這句把 CAP 的取捨講反了,也和他自己下一句「資料可能不一致」矛盾。CAP 的正確讀法是:分散式系統必須容忍網路分區(P 不是可以放棄的選項),因此在分區發生時只能在一致性(C)與可用性(A)之間二選一。地理分散的唯讀副本選的是可用性,代價是最終一致性。另外 CAP 只描述分區期間的行為,平時的取捨其實是延遲與一致性(PACELC)。
依據: Gilbert & Lynch 對 CAP 的形式化證明(2002);Abadi 的 PACELC(2012)
16. Design system 與 monorepo
41:47
「that would be our scale level number seven where we scale our organization」這裡的編號跳號了。影片實際出現過的階層是 Level 0(純 client-server)、Level 1(加 CDN)、Level 3(邊緣運算+分散式資料庫)、Level 4(API Gateway+BFF+負載平衡)、Level 5(微前端),接著直接跳到 Level 7,中間的 2 與 6 沒有對應的畫面。這是自創的教學編號而非業界標準,記住演進順序即可,別把數字當共通語言用在面試裡。
依據: 影片內出現的階層標題投影片(0:45、12:58、24:05、29:05、36:45、39:00)

5. 推薦三個下一步

1. 往下挖深:把 Core Web Vitals 變成能動手改的清單

影片把 web performance 定為前端系統設計的第一順位,卻只用 LCP/CLS/INP 當量尺,沒說每個指標實際被什麼拖慢、該怎麼量與怎麼修。這是整條推理鏈裡最常被面試官追問細節的缺口。

YouTube 搜尋:Core Web Vitals optimization LCP INP INP debugging long tasks web performance audit Chrome DevTools

2. 往旁邊對照:微前端的反方意見與 modular monolith

影片用康威定律直接推出微前端,但沒有談它的代價(重複相依、跨應用狀態、版本失控),也沒有比較「不拆系統只拆模組」這條路。聽過反方論點,才知道什麼規模下該拆、什麼規模下不該。

YouTube 搜尋:micro frontends downsides modular monolith vs micro frontends module federation problems

3. 往上應用:拿一場完整的前端系統設計模擬面試練手

本片給的是骨架與順序,但沒有示範在時間壓力下怎麼取捨、怎麼回應面試官的追問。看一場真實節奏的模擬面試,能把這套心智模型從「看得懂」變成「講得出來」。

YouTube 搜尋:frontend system design mock interview frontend system design interview news feed senior frontend interview whiteboard

📄 全部影片 · 主題區: 前端底層與系統設計