使用方法
- 打开页面时四只输入框已经填好默认值:工作 25 分钟、短休 5 分钟、长休 15 分钟、每 4 轮长休一次——这就是这套工作法最通行的配置,直接点「开始」就能用。
- 想让节奏更适合自己,改数字即可:写作、编程这类需要长时间连续投入的任务,可以把工作时长调到 40~50 分钟;开会、批邮件这类碎片任务,调到 15 分钟反而更容易坚持。
- 在任意一只输入框里按 Enter 会直接开始或暂停,不必去点按钮。「自动进入下一段」默认勾选,工作段一结束就自动切到短休,中途不会停下来等你。
- 想手动控制节奏时,取消「自动进入下一段」,然后每段结束时点一次「跳过本段」,由你决定什么时候进入下一段。
- 第一次用建议点「开启浏览器通知」,浏览器会弹出授权询问;同意之后,即使你切到了别的标签页做别的事,阶段结束也会弹出系统通知。不想授权也没关系,页面标题同样会显示剩余时间。
这个番茄钟能解决什么问题
一是把「我要专注两小时」这种没法执行的计划,换成能执行的段落。人对「还有 25 分钟」的判断远比对「还有两小时」准确,倒计时牌把抽象的意志力换成了一个会走动的数字。
二是给多任务打断一个明确出口。工作时忽然想起要回一条消息、查一个资料,不要马上做,把它写在旁边,等当前工作段结束的短休里一次性处理。四轮循环里一共有 3 次 5 分钟短休,足够消化掉大部分零碎念头。
三是让「已经做完了多少」可计量。页面上「已完成工作段」是一个只增不减的计数器,一天结束回看这个数字,比回忆「今天好像挺忙」要可靠得多。按默认参数排一个 8 小时工作日,可以排出 3 个完整四轮循环再加 3 个工作段,合计 15 个工作段、也就是 375 分钟的纯工作时长。
四是长休放在正确的位置上。长休不是「累了就休」,而是固定在第 4 轮工作之后,避免你因为一时兴奋连做六七个工作段、把后半天的状态提前透支掉。
本页不做这些事:不统计你每天完成了多少段并画趋势图,不做多人协作的看板,也不做白噪音播放。它只负责把四段循环的节奏走准,并把结果交回给你。
原理:25+5 循环与「时间戳差」计时
25 与 5 从哪来。番茄工作法(Pomodoro Technique)由 Francesco Cirillo 在 1980 年代末提出,他当时用的是一只番茄形状的厨房定时器,随手拧到的刻度就是 25 分钟。后来的规范化描述把它固定为「25 分钟工作 + 5 分钟短休,每 4 轮工作之后换成 15 分钟长休」。这个番茄钟的默认值就是这套参数:工作时长 25 分钟 = 1500 秒 = 1500000 毫秒,短休 5 分钟 = 300000 毫秒,长休 15 分钟 = 900000 毫秒。
一个完整四轮循环有多长。4 轮工作 = 100 分钟,中间夹 3 次短休 = 15 分钟,循环末尾加 1 次长休 = 15 分钟,合计 130 分钟(2 小时 10 分),其中纯工作 100 分钟,占比 76.92%。注意长休只出现在第 4 轮之后,第 1~3 轮之后都是短休,所以循环里短休是 3 次而不是 4 次。
关键在计时方式,不在定时器。这套工具不用 counter-- 那种「每响一次就减 1 秒」的累加写法。开始一段时只记下一个终点时间戳 deadline = Date.now() + 本段毫秒数,之后每 250 毫秒刷新一次,剩余时间一律现算:remain = deadline - Date.now()。这样做的原因见下一节——浏览器的后台节流会把定时器频率压到很低,累加式必然走慢,而时间戳差的误差只取决于「时钟精度」,与「定时器响了没有」无关。
为什么刷新用 250 毫秒而不是 1000 毫秒。显示的秒数用 Math.ceil(remain / 1000) 取整,250 毫秒采样能保证秒数跳变时刻的误差不超过四分之一秒,肉眼看不出停顿;而 1500 秒的一段工作会产生 6000 次刷新,用 1000 毫秒则只有 1500 次、跳秒会略显卡顿。这个频率对性能没有影响,因为每次刷新只做一次减法。
提醒走两条路。一条是 document.title:计时中把标题改成「▶ 12:34 工作」,你切到别的标签页时,标签上直接就能看到剩余时间;另一条是 Notification API,在阶段切换时弹出系统级通知。标题不需要任何授权,通知需要用户在交互后授权,并且只在 HTTPS 页面(localhost 例外)可用。
长休判定用的是取模。每完成一个工作段就把计数加 1,然后判断 done % every === 0。默认 every = 4,于是第 4、8、12 个工作段之后都进入长休。这个写法把「每 4 轮」从一句描述变成了一个恒等式,不需要额外维护「第几轮」这个状态。
完整示例(默认 25 / 5 / 15 / 每 4 轮)
下面按番茄钟的默认参数走一遍。条件与页面打开时的默认值完全一致:工作 25 分钟、短休 5 分钟、长休 15 分钟、每 4 轮长休一次。从第 1 轮工作开始,时间轴是这样的:
- 第 1 轮工作 0~25 分钟,随后短休 25~30 分钟;
- 第 2 轮工作 30~55 分钟,随后短休 55~60 分钟;
- 第 3 轮工作 60~85 分钟,随后短休 85~90 分钟;
- 第 4 轮工作 90~115 分钟,因为
4 % 4 === 0,这次进入的是长休 115~130 分钟。
整个循环封闭在 130 分钟上,此时「已完成工作段」显示 4 段,第 5 轮工作从 130 分钟处重新开始。
按这个节奏排一个 8 小时(480 分钟)工作日:480 ÷ 130 = 3.69,能放下 3 个完整循环共 390 分钟,余下 90 分钟正好再做 3 个工作段(工作 25 + 短休 5 + 工作 25 + 短休 5 + 工作 25 = 85 分钟),全天合计 15 个工作段、375 分钟纯工作,也就是 6 小时 15 分。如果换成「连续工作 8 小时」的排法,看起来时间更多,但中间没有段落边界,实际能维持高强度的时长通常比这个数字低。
时长档位与四轮循环对照表
下表固定「每 4 轮长休一次」,只改工作时长,看一个循环要花多久。短休与长休按时长的常用比例给出(短休约为工作时长的 1/5,长休约为 1/3):
| 工作时长 | 短休 | 长休 | 一个四轮循环 | 纯工作占比 |
|---|---|---|---|---|
| 15 分钟 | 3 分钟 | 10 分钟 | 79 分钟 | 75.9% |
| 20 分钟 | 4 分钟 | 13 分钟 | 105 分钟 | 76.2% |
| 25 分钟(默认) | 5 分钟 | 15 分钟 | 130 分钟 | 76.9% |
| 30 分钟 | 6 分钟 | 18 分钟 | 156 分钟 | 76.9% |
| 45 分钟 | 9 分钟 | 27 分钟 | 234 分钟 | 76.9% |
| 50 分钟 | 10 分钟 | 30 分钟 | 260 分钟 | 76.9% |
把工作时间拉长,纯工作占比基本不变(都在 76% 附近),因为休息也按同一比例变长了——加长工作段并不会提高单位时间里的专注比例,它只是把节奏整体放慢。真正影响产出的是「一个工作段里有没有被打断」。
下表是默认参数下一次循环的逐段时刻表,和上面的时间轴一致,可以对照着看:
| 时段 | 起止(分钟) | 时长 |
|---|---|---|
| 第 1 轮工作 | 0 ~ 25 | 25 分钟 |
| 第 1 段短休 | 25 ~ 30 | 5 分钟 |
| 第 2 轮工作 | 30 ~ 55 | 25 分钟 |
| 第 2 段短休 | 55 ~ 60 | 5 分钟 |
| 第 3 轮工作 | 60 ~ 85 | 25 分钟 |
| 第 3 段短休 | 85 ~ 90 | 5 分钟 |
| 第 4 轮工作 | 90 ~ 115 | 25 分钟 |
| 长休 | 115 ~ 130 | 15 分钟 |
输入范围、边界与精度说明
- 工作时长 1~180 分钟。大于 180 分钟就没有必要再用分段节奏了;小于 1 分钟会让「切换阶段」本身比工作还频繁。提交小数、负数或空值都会被拒绝,并提示具体允许范围。
- 短休与长休各 1~60 分钟。上限设 60 是因为休息长到一小时以上,用户通常会直接离开页面,提醒也就失去意义。
- 「几轮后长休」2~12 轮。下限是 2,因为设成 1 就等价于「每次工作之后都长休」,失去了短休的作用;上限 12 是为了让取模计数不至于在页面上显示成两位数而看不出进度。
- 后台节流最多让提醒晚 60 秒,但时间一定准。Chrome 对后台标签页的定时器下限约 1 秒;标签页隐藏超过 5 分钟后进入 intensive throttling,下限进一步压到约 60 秒。假设你用累加式写法,60 秒真实过去、计数器只前进 1 秒,漂移高达 98.33%,一小时墙钟时间只走 60 秒、少记 3540 秒。本页用时间戳差,代价只是「阶段切换最多晚 60 秒」,一旦切回前台或节流窗口结束,剩余时间立刻被算回真实值。
- 前台定时器也有抖动。即便在前台,
setInterval的一次回调也可能比设定时间晚 4 毫秒左右。25 分钟里有 1500 次回调,最坏累计偏差约 6 秒(占 1500 秒的 0.4%)。这 6 秒只会影响「秒数跳动」的观感,不影响终点时间戳。 - 用的是墙钟,不是单调时钟。
Date.now()返回 Unix 毫秒,能表示的年份上限约 285421 年,对本页毫无压力。但它跟随系统时间走:合上笔记本睡 2 小时再打开,这 7200 秒会被算作已经过去,页面会直接把阶段收尾——这正是「真实经过了多久」的语义。如果你要的是「设备真正运行了多久」,需要用不受系统时间调整影响、且在部分平台上睡眠期间会暂停的单调时钟performance.now()。 - 显示取整方向是「向上取整」。剩余 1 毫秒时
Math.ceil显示 00:01,Math.floor会显示 00:00;用后者会让人在最后一秒看到「已经归零但还没切换」的场面,所以显式选用向上取整。 - 默认值与正文示例、对照表三处一致:全部是 25 / 5 / 15 / 4。换过参数后如果对不上,点「重置」即可回到这一组。
常见问题
为什么一定要每 4 轮才长休一次,不能累了就休?
因为「累了才休」的判断发生在疲劳之后,那时你已经做完了低质量的一段。把长休固定在 done % 4 === 0 这个位置,是在疲劳累积到临界点之前先把它清掉。当然这个数字不是硬规定,把「几轮后长休」改成 3 或 5 都可以,只要它固定,节奏才有意义。
切到别的标签页写代码,计时会不会走慢?
不会。页面显示的剩余时间是每次刷新时用 deadline - Date.now() 现算的,浏览器压低的只是「多久刷新一次」,不是「时钟走多快」。副作用是阶段切换与提醒最多可能晚 60 秒,切回标签页的瞬间就会纠正。
「跳过本段」和「暂停」有什么区别?
「开始 / 暂停」只冻结计时,当前处于哪一段、已经做完几段都不变;「跳过本段」是直接把这个阶段判为结束,会按规则推进到下一段——在工作段里点它,计数器会加 1,并按取模结果决定进短休还是长休。想提前收工用暂停,想提前进入休息用跳过。
浏览器通知一直不弹出来是哪里的问题?
按顺序排查三件事:一是地址栏是否是 HTTPS(http:// 页面与未加密的内网地址拿不到通知权限,localhost 除外);二是站点权限里通知是否被设成了「阻止」,被阻止后不会再弹授权框,需要手动改回「询问」;三是操作系统的「专注模式 / 勿扰模式」是否开着,它会把系统通知整体静音。以上都排除后,标题提醒仍然有效。
关掉页面,计时会继续吗?
不会。计时状态只存在于当前页面内存里,没有写进浏览器存储,刷新或关闭就归零,这是刻意的——本页不保存任何记录。需要跨设备继续的长时间任务,建议把它交给系统自带闹钟,或者记在「在线记事本」这类能保存的工具里。
工作时长设成 60 分钟,是不是效率更高?
番茄钟把工作段拉长之后,单位时间的专注占比几乎没变。默认 25/5/15 一圈 130 分钟、纯工作占 76.92%;把工作段整体拉长,休息也按比例变长,占比仍在 76% 附近。拉长工作段唯一确定的变化是「每个段落更不容易被打断」,所以适合需要深度上下文的任务;而 25 分钟的段落适合本身就能被切开的任务。
能不能把它当成通用的倒计时牌用?
把它理解成「固定分段循环的训练节奏」更准确。你可以把工作时长设成 1 分钟、短休设成 1 分钟,得到一个快速循环,但这已经不是工作法本身了。要按某个具体截止时刻往回提醒,用倒计时类工具意图更清楚;要测每一段的原始耗时,用秒表类工具更合适。
一天做几个工作段算正常?
按默认参数排满 8 小时可以得到 15 个,但这只是数学上的上限,中间不含开会、吃饭和上下楼。实际使用时更常见的做法是先把当天最需要专注的几件事拆成工作段,做完就停,不必把格子填满。计数器的作用是让你知道真实完成了多少,而不是逼你去追一个更大的数字。