用纯前端实现一个间隔重复闪卡工具:从SM-2到简化调度的取舍
一、背景
背单词、记知识点最怕的不是记不住,而是“记住了又忘了”。间隔重复(Spaced Repetition)的思路是:在快要遗忘的时候再复习一次,每次复习成功后把下次间隔拉长。Anki 背后的 SM-2 算法和近年流行的 FSRS 都是这个思路。最近我在华为云 AI 开发者空间里用 AI Shell 做了一个纯前端的闪卡小工具“碎片背卡”,这篇记录一下调度算法的设计取舍。
二、需求与约束
- 纯前端单页:index.html + style.css + app.js,不依赖后端和第三方 CDN;
- 数据全部存在浏览器 localStorage;
- 三档评分:记住 / 模糊 / 忘记,自动安排下次复习时间;
- 统计今日待复习数量、连续打卡天数、累计复习次数;
- 深浅色自适应、适配手机。
三、为什么不直接上完整 FSRS
完整的 FSRS 用稳定性(Stability)、难度(Difficulty)和可提取性(Retrievability)三个变量建模记忆,参数需要用大量复习日志拟合。一个刚上手的个人小工具没有历史数据,直接套默认参数,效果未必比简单规则好,代码复杂度却高出很多。所以我选了“SM-2 思路 + 三档评分”的简化版本。
四、简化调度规则
每张卡片保存四个字段:interval(间隔天数)、ease(难度系数,初始 2.5)、reps(成功复习次数)、due(下次到期日期)。评分后按下面的规则更新:
- 记住:ease 加 0.1(上限 3.5);第一次成功间隔为 1 天,第二次为 3 天,之后 interval 乘以 ease;
- 模糊:ease 减 0.15(下限 1.3),interval 乘以 1.3,增长放缓;
- 忘记:ease 减 0.2(下限 1.3),interval 重置为 1,明天再复习。
ease 的上下限很重要:没有下限,一张总忘的卡会把系数压到接近 1,间隔几乎不再增长,陷入“每天都要背”的死循环;没有上限,一张简单的卡间隔会膨胀得过快。
五、几个实现细节
- 按日期而不是时间戳判断到期:due 只存 YYYY-MM-DD,避免跨时区或晚上十一点复习导致“明天”提前到来;
- 评分按钮预显示下次间隔:例如“记住 · 6天后”,让用户知道每个选择的后果,减少随手乱点;
- 连续打卡:记录每天是否有复习,从今天往前数连续的天数,中断即清零;
- 导入导出 JSON:localStorage 换浏览器或清缓存就会丢,提供导出备份是必须的。
六、开发过程中的体会
需求写给 AI 时,把“只在项目目录内读写文件、不调用任何云资源”这类边界写清楚,生成过程会可控得多。AI 一开始倾向于把算法设计得很复杂,我在需求里明确了“三档评分、简化版”,它最后收敛到了上面这套规则。生成后用 python3 -m http.server 在本地预览,再逐个检查翻转、评分和统计是否正常。
七、总结
间隔重复的核心并不神秘:成功就拉长间隔,失败就缩短,再给难度系数加上合理的边界。对个人小工具来说,简单、可解释的规则往往比复杂模型更实用。等积累了足够的复习日志,再考虑引入 FSRS 做参数拟合也不迟。
项目代码已开源在 GitCode:hid86006757/study-flashcard。
- 点赞
- 收藏
- 关注作者
评论(0)