前端系統設計 - 設計聊天系統 (Chat System)

2024年1月24日

💎 加入 E+ 成長計畫 與超過 250+ 位軟體工程師一起在社群中成長,並且獲得更深入、系統性軟體工程內容

本篇詳細解說本收錄在 E+ 的前端系統設計專題

設計聊天系統 (Chat System) 很普遍,非常多公司都有做,也是系統設計面試很經典的問題。這邊我們會列下設計聊天應用的前端,應該要考量什麼面向,協助大家在準備面試時,知道要往哪些方向思考。

如果你想看每個思考面向,我們會如何回答,可以在 E+ 的《前端系統設計 - 設計聊天系統 (Chat System)》一文讀到

先釐清需求

不論在面試,或者在工作時,當聽到要設計一個聊天系統,一定要先釐清需求。假如面試官問你,或者工作時 PM 跟你提說要設計聊天系統,你會有哪些想釐清的問題呢? 在往下讀之前,不妨自己先想一想。

在思考這問題時,推薦可以先回到使用者的角度,平常大家有用的不論是跟朋友家人用的 Line,或者 Instagram 中的聊天,又或者 E+ 社群用的 Discord,這些都是聊天系統的範疇。可以想看看,這些不同聊天系統,分別有哪些不同,可以從這些差異去想要釐清的問題。

關於聊天系統,以下的問題是推薦要釐清的

  • 這個聊天系統的目標用戶是誰? 上面提的 Line、Instagram、Discord 目標族群很不同,都是聊天系統,但設計上會有差異
  • 最基本的功能涵蓋什麼? 收發訊息外,需要有歷史記錄嗎? 要有聊天對象列表嗎?
  • 收發的訊息類型是純文字的嗎? 還是要支援不同多媒體? 例如圖片、語音、影片等
  • 聊天是即時的嗎? 還是非即時的聊天?
  • 聊天都是 1 對 1 的嗎? 需要有群組聊天功能嗎?
  • 要支援離線 (offline) 功能嗎?

除了上面這些,還有細部可以問的,包含

  • 要有通知的功能嗎?
  • 要有對方正在輸入訊息的功能嗎? (例如 Discord 可以看到別人正在打字中)
  • 要有按表情符號的功能嗎? (例如 Discord 每個訊息都可以按表情符號)
  • 要支援收回訊息嗎?
  • 要支援國際化 (i18n) 嗎?

從架構的角度看的技術討論

我們先從最基本的 1 對 1 聊天,要支援聊天對象列表、歷史訊息,要是即時聊天,僅需用純文字,同時要支援離線功能。當看到上面這些功能,大家會如何設計前端呢?

聊天訊息要包含哪些狀態?

對前端來說,狀態管理往往是挑戰之一。對於 1 對 1 聊天,第一個要思考的是聊天訊息的狀態。以常見的聊天應用,該包含哪些狀態? 為什麼要有這些? 這部分如果設計的好,對功能開發也會比較容易照顧不同面向。

渲染方式選擇,要選 CSR 或 SSR?

對於前端來說,不同種類的應用,會分別適合不同類的渲染方式。假如今天被問說聊天應用該選哪一種,你會如何回答呢? 回答這問題前,可以先思考,CSR 與 SSR 分別適用的情境。在思考哪個特性比較適合聊天應用。

離線支援選哪種存儲方案?

現在有許多聊天應用都有支援離線,換句話說,今天即使網路突然斷線,也可以點其他聊天對象,去看先前聊天過的歷史訊息,此外也可以發送訊息 (但要等到重新有網路後才會發送)。要做到離線支援,可以分兩塊來討論。第一塊是假如用戶離線後重新整理,要如何確保有 HTML、CSS、JavaScript? 你會選擇用什麼來存呢?

此外,聊天的訊息應該被存在客戶端的哪裡呢? 談到前端的存儲,多數人第一時間可能會想到 cookie、sessionStorage 以及 localStorage (差別詳見此篇)。除此之外,先前我們也有介紹過 IndexedDB。在這些選項中,你會選哪一個呢?

與後端共同制定 API

前端系統設計面試,也常會被問到跟後端共同制定的 API 該如何設計,以聊天應用來說,最基本的需求來說,至少需要以下的 API 來滿足

  • 獲取聊天對象列表
  • 獲取歷史訊息
  • 傳送訊息
  • 接收訊息

大家可以思考一下,被問到這些接口,你會如何設計呢?

基本追問題

除了上面的討論面向外,很可能在面試中有以下的追問:

  • 追問一:如何在瀏覽器的多個分頁同步
  • 追問二:如何實作即時聊天 (該用哪個協定? 為什麼?)
  • 追問三:效能優化可以從哪些面向切入

延伸問題

以下列出幾個在面試中常見的延伸問題。推薦大家也可以準備

  • 延伸問題一:支援各種類型對話該如何設計? 例如圖片、語音?
  • 延伸問題二:表情符號功能要如何設計?
  • 延伸問題三:群組聊天該如何設計?
  • 延伸問題四:串聊 (Threads) 要如何設計?
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們