前端系統設計 - 設計聊天系統 (Chat System)
2024年4月1日
本篇詳細解說本收錄在 E+ 的前端系統設計專題
設計聊天系統 (Chat System) 很普遍,非常多公司都有做,也是系統設計面試很經典的問題。這邊我們會列下設計聊天應用的前端,應該要考量什麼面向,協助大家在準備面試時,知道要往哪些方向思考。
如果你想看每個思考面向,我們會如何回答,可以在 E+ 的《前端系統設計 - 設計聊天系統 (Chat System)》一文讀到。
先釐清需求
不論在面試,或者在工作時,當聽到要設計一個聊天系統,一定要先釐清需求。假如面試官問你,或者工作時 PM 跟你提說要設計聊天系統,你會有哪些想釐清的問題呢? 在往下讀之前,不妨自己先想一想。
在思考這問題時,推薦可以先回到使用者的角度,平常大家有用的不論是跟朋友家人用的 Line,或者 Instagram 中的聊天,又或者 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) 要如何設計?