前端系统设计 - 设计聊天系统 (Chat System)

2024年4月1日

💎 加入 E+ 成長計畫 與超過 350+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

本篇详细解说本收录在 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) 要如何设计?
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們