无限层级嵌套
P0评论可对任意评论回复,无深度硬限制(实测支持 50 层以上)。
实现要点:数据库采用邻接表(parent_id)+ 物化路径(path,如 /1/7/23/)双写。邻接表便于写入,物化路径便于「取整棵子树」与「判断祖先关系」。
This page is not translated yet
The interface, navigation and community content are bilingual. The long-form body of this page is still in Chinese. The translation work is tracked as task I18N-10.
Module 05 · V1.0 · Threaded Comments
社区的深度,把讨论从线性变成树形
实现任意深度嵌套的评论树,支持折叠、排序、分页、单串展开与实时更新,让长尾讨论可读、可定位、可参与。
评论是社区区别于内容平台的核心价值。树形结构让同一话题下的多个分支并行生长,是 Reddit 最难以被模仿的资产。
共 10 个功能点,每个功能点给出实现要点,可直接作为开发任务的描述。
评论可对任意评论回复,无深度硬限制(实测支持 50 层以上)。
实现要点:数据库采用邻接表(parent_id)+ 物化路径(path,如 /1/7/23/)双写。邻接表便于写入,物化路径便于「取整棵子树」与「判断祖先关系」。
单条评论可折叠其所有子评论;提供「折叠全部」「展开全部」;已读的子树自动记忆折叠状态。
实现要点:折叠状态存在前端 store 与 localStorage,登录用户同步到服务端以便跨设备一致。折叠时保留一条概括行(作者 + 子评论数)。
Best(最佳)、New(最新)、Old(最旧)、Controversial(争议)四档,每层递归应用。
实现要点:Best 使用评论热度公式(票数 + 时间衰减 + 子评论数加权),让「既有共鸣又有讨论」的评论排前。
深层评论可点击「继续此讨论串」进入独立页面,只展示该分支,避免横向缩进吃光空间。
实现要点:独立页 URL 形如 /c/{community}/post/{id}/comment/{cid},服务端按 path 前缀查询子树,页面顶部提供返回上级讨论的单链入口。
每条评论有独立锚点与永久链接,可被分享与引用。
实现要点:锚点使用评论 ID;从外链进入时自动展开该评论的全部祖先、高亮目标评论并滚动定位。
首屏只加载顶层评论的前 N 条,子评论按需加载;「加载更多回复」按批次展开。
实现要点:接口支持 parent_id 与 depth 参数,默认只返回 2 层;深层通过 /comments?parent_id=&cursor= 分页拉取,控制单次响应体积。
支持富文本、@提及、引用、表情、图片插入、代码块;支持保存为草稿。
实现要点:回复时若引用了某层,自动带入引用块并保留原评论链接。@提及触发输入联想与通知。
每条评论独立支持投票、回复、分享、收藏、举报、屏蔽作者、保存为「稍后读」。
实现要点:操作菜单在悬停/长按时出现,移动端为底部弹出层。屏蔽作者后该作者评论折叠为「已屏蔽」一行。
已有用户正在浏览的帖子,新评论通过 SSE/WebSocket 实时插入并提示「N 条新评论」。
实现要点:不直接插入列表(避免阅读位置跳动),而是顶部悬浮提示条,用户点击后合并,并保持当前阅读位置。
评论支持锁定、置顶、隐藏(collapsed by default)、待审、已删除等状态。
实现要点:被举报达阈值的评论自动折叠但保留「显示」按钮;版主可一键标注并回复。
3 条关键交互的分步流程,按用户体验顺序描述,可直接作为前端开发与可用性测试脚本。
在评论框输入内容,编辑器内实时渲染 Markdown 预览。
点击回复,评论立即以「发送中」骨架插入目标层级下方,缩进正确。
服务端确认后替换为真实评论并更新父评论的子评论计数。
失败则标记为「发送失败 · 重试」,内容不丢失。
缩进层级超过 6 层后,不再继续增加缩进,改为「左侧竖线 + 层级色标」并显示「继续此讨论串 →」。
点击后进入独立页面,只渲染该分支,顶部提供返回上级讨论的入口。
在独立页发帖回复后,返回主帖时可跳回原位置。
点击评论左侧的折叠标记(或评论头部),折叠该条以下的全部子树。
顶部工具条提供「折叠全部顶层评论」,便于跳到下一个顶层分支。
被折叠的子树若包含自己参与的评论,折叠行显示「你参与过」提示。
6 条硬性约束。这些规则应当在服务层强校验,而非仅在前端提示。
评论长度 1–10000 字符;TL0 用户每 10 分钟最多 10 条。
同一用户对同一帖子的连续评论间隔 ≥ 10 秒,防止刷屏。
嵌套深度超过 50 层时,前端折叠展示并提示「继续此讨论串」,不再渲染更深层级。
父评论删除后子评论保留,父级位置显示 [已删除],保证上下文不丢失。
锁定(Lock)状态下禁止新增评论,但已有的可继续投票与折叠。
评论排序默认「最佳」,排序偏好按用户持久化,逐层递归应用。
| 邻接表 parent_id | 写入 O(1),取子树需递归 | 写多读少 | 与物化路径组合使用 |
| 物化路径 path | 取子树一条 LIKE 查询,移动代价高 | 读多写少 | 评论场景最优 |
| 嵌套集 Nested Set | 查询极快,写入需重排 | 几乎不变的结构 | 不适合高写入评论 |
| 闭包表 Closure | 任意祖先/后代查询快,表体积大 | 关系复杂场景 | 可作为审计补充 |
本模块涉及的 5 张表。完整字段、索引与说明见「数据表设计」页。
本模块的设计参照了哪些产品,具体参照了什么。
无限嵌套 + 继续此讨论串 + 单条永久链接,几乎无出其右。
Hacker News
极简折叠,无动画优先,性能极佳。
Discourse
主题内位置记忆与实时新回复提示,长贴体验优秀。
贴吧
两层(楼 + 楼中楼)结构,移动端友好度最好,是降级方案。
本模块交付时应当达到的量化目标。未达标即视为该模块未完成。
竞品踩过的坑,以及本模块在实现时最容易犯的错误。
纯邻接表取整棵子树需要递归 CTE,深度大时性能差,必须配合物化路径。
物化路径的更新代价高(移动子树要批量改 path),评论树几乎不移动,是最合适的场景。
递归渲染深层组件会导致栈溢出与性能崩溃,需限制渲染深度并改为懒加载。
移动端若用固定缩进,30 层后内容宽度归零,必须切换到竖线 + 色标方案。
折叠状态若只存前端不持久化,用户刷新后会全部展开,体验割裂。