博客小记 · 文章

+ 有更新

博客小记:给博客文章加一个“有更新”

有更新更新于 2026年5月7日
+新增 / 调整
  • 有更新2.0
  • 今天对博客的"有更新"功能进行了一个简单的调整。
  • 之前的更新提示是基于文章内容改动来界定在文章列表页面是否显示“有更新”标识 ,它表达的是 “这篇文章发布后曾经更新过”,不是“对当前读者来说有未读更新”。如果不加消失条件,它确实会慢慢失去信息量。
  • 所以我想了一下,将它做成未读更新的逻辑。这个逻辑实现的一个简单方案是:
Pasted image 20260506124113

有些文章不是写完就结束的。

尤其是技术类、工具类、经验类文章,过一段时间再回头看,经常会发现里面有些判断过时了,有些做法变了,有些坑后来绕明白了。如果只是悄悄改掉,读者看不出来这篇文章发生过变化;如果每次都重新发一篇,又显得太重。

所以我想给博客加一个很小的功能:当一篇文章发布后又更新过,在列表里显示一个绿色的“有更新”标识。进入文章后,也能看到这次更新大概调整了什么。
这件事听起来简单,但做的时候我发现它其实很考验一个博客系统的分寸感。


最初的想法

我一开始想要的是一种很轻的提示。
文章列表里,标题旁边多一个绿色小标签。读者扫列表的时候能知道:这篇文章后来又补过东西。

文章详情页里,在正文开头放一个更新提示卡片,告诉读者更新时间,以及大概新增、调整、移除了哪些内容。

这个方案的好处是克制。它不会改变文章本身的阅读节奏,也不会把博客变成一个代码审查页面。


版本一:轻量更新卡片

Pasted image 20260506123950

第一版方案很直接。

数据层增加几个字段:

  • content_updated_at:正文最近一次更新时间

  • previous_content:更新前的纯文本快照

  • previous_html:更新前的 HTML 快照

当一篇已经发布的文章正文发生变化时,系统会记录第一次变化前的内容快照,并更新 content_updated_at。列表页只需要判断:


content_updated_at > published_at

如果成立,就显示“有更新”。

文章页则用 previous_content 和当前 content 做一个简单的段落级比较,提取出新增段落和移除段落,展示在正文前面的更新卡片里。
这个版本很适合博客。它不是最精确的,但它足够自然。

中间的尝试:正文内 diff

后来我又尝试了一版更“精确”的方案:像代码 diff 一样,把变更直接插入到正文对应位置。
新增内容前面显示 +,删除内容显示 -,更新前后用 DU 标识。技术上是把上一版 HTML 和当前 HTML 拆成块级节点,再用类似 LCS 的方式对齐,尽量找到变化发生的位置。

这版在工程上是可行的,但体验上很快暴露问题:它太打断阅读了。

博客文章和代码不一样。代码天然是一行一行被审查的,而文章是连续阅读的。把 diff 标记插进正文,会让读者的注意力从“读文章”变成“审改动”。

这不符合博客的气质。


再尝试:GitHub 风格 diff

Pasted image 20260506124002

我又试了一版更完整的 GitHub diff 风格:文件头、hunk、左右行号、+/- gutter、行内词级高亮。

技术上更完整,也更像真正的 diff。它会先把内容切成行,用最长公共子序列找到相同和变更区域,再只展示变更附近的上下文。替换行内部再做一次词级 diff,让新增和删除的词更明显。

但最后我还是把它撤掉了。
原因很简单:它太像一个开发工具了,而不是一篇博客文章的一部分。

这个功能如果是给后台编辑器看的,它很好;但如果放在前台读者阅读路径里,它就显得入侵性太强。


最终方案:回到轻量提示

最后我回到了第一版。

列表页只显示一个绿色“有更新”标识。文章页只在开头显示一个温和的更新卡片:

  • 更新于哪一天

  • 新增 / 调整了哪些内容

  • 上一版中移除了哪些内容

正文保持正文,更新说明保持说明。

这个方案没有 GitHub diff 那么精确,但它和博客更协调。读者可以先知道文章发生过变化,再决定要不要关注具体变化;如果只是想正常阅读,也不会被打断。


技术上的几个取舍

这里面有几个细节比较重要。

  1. 不能每次自动保存都覆盖上一版快照。

如果编辑已发布文章时每敲几下就自动保存一次,而系统每次都刷新 previous_content,那最后对比出来的就只是最近几秒钟的变化,完全没有意义。

所以现在的逻辑是:发布后第一次正文变化时,保存“编辑前版本”作为快照;之后继续编辑,只更新 content_updated_at,不反复覆盖这份对比基准。

  1. 只把正文变化算作“有更新”。

标题、分类、封面、置顶状态这些元数据变化,不应该让文章显示“有更新”。读者关心的是正文内容有没有变化。

  1. 列表查询要轻。

列表页不需要带出 previous_contentprevious_html,只需要 content_updated_at。真正进入详情页时,再读取完整字段用于生成更新说明。


有更新2.0

今天对博客的"有更新"功能进行了一个简单的调整。

之前的更新提示是基于文章内容改动来界定在文章列表页面是否显示“有更新”标识 ,它表达的是 “这篇文章发布后曾经更新过”,不是“对当前读者来说有未读更新”。如果不加消失条件,它确实会慢慢失去信息量。

所以我想了一下,将它做成未读更新的逻辑。这个逻辑实现的一个简单方案是:

  1. 每篇文章的 content_updated_at 就当作更新版本号。

  2. 用户进入文章详情页后,在本地记录:

    post:updateSeen:{slug} = content_updated_at
  3. 列表页显示“有更新”的条件改成:

    content_updated_at > published_at && 本地记录的 seenUpdatedAt < content_updated_at
  4. 所以:

    • v1 发布,没有标识

    • 更新到 v2,列表显示“有更新”

    • 用户打开 v2 后,本地记录已读,标识消失

    • 后来更新到 v3,content_updated_at 变大,标识重新出现

这样就解决了文章版本“v2 看过了,到 v3 时分不清是不是旧提示”的问题。


版权声明

本文内容版权归作者或相关权利人所有。转载、引用或其他使用请遵循相应授权条款,并保留本文链接。

本文链接:https://xuyi.dev/2026-05-06-kqdi7x