HIIT间隔训练计时器

把训练段、休息段、轮数和准备倒计时逐项填好,剩下的交给计时器:每段自动切换、倒数 3 秒有提示音、全程进度一目了然,页面切回后台也不会把时长算歪。

待开始 5:50 准备 5 秒 · 8 轮 × 30 秒训练 / 15 秒休息
全程时长5:50
阶段数16 段
训练合计4:00
休息合计1:45
有效训练占比68.6%

上面这组数字是默认方案的示例:准备 5 秒 + 8 轮 × (30 秒训练 + 15 秒休息),末轮休息不计,全程 5 分 50 秒。改完任意一个输入框,方案摘要会立刻跟着重算。

提示:在输入框里按 Enter 会重新校验并刷新方案摘要;开始之后按 Esc 可以随时停下来。

使用方法

  1. 先填四个参数:训练时长 30 秒、休息时长 15 秒、轮数 8、准备倒计时 5 秒,这就是页面打开时的默认方案,摘要区显示「全程 5:50、16 段」。
  2. 两个勾选项按需要留:勾上「结束后保留末轮休息」会多做一段休息;勾上「段间提示音」才会在切换和倒数 3 秒时发声,浏览器策略要求先在这页上点过一下才允许播放声音。
  3. 点「开始训练」。先是 5 秒准备倒计时,接着进入第 1 轮 30 秒训练;训练段结束时提示音变高、阶段标签切成「休息」,休息段结束时提示音变低、回到「训练」。
  4. 大号数字是当前这一段的剩余整秒,下方细条是全程进度,两个数字一起看:前者告诉你这一段还剩多久,后者告诉你整套还剩多少。
  5. 想中途停一下,点同一个按钮(文字会变成「继续」);点「重置」回到待开始状态;点「载入示例」恢复默认方案。参数改动不会打断正在跑的计时,只有点「重置」或重新开始才会按新参数重建。

这个 HIIT间隔训练计时器能解决什么问题

一是把「训练 30 秒、休息 15 秒、做 8 轮」从记忆里搬到屏幕上。HIIT 的强度全靠时间比撑着,靠心里默数容易出现一个致命偏差:训练段越数越短、休息段越数越长,最终训练量比计划低两三成。计时器把每一段都钉死在秒上。

二是不用一直盯着屏幕。动作做到位的时候人是没法看表的,所以在倒数 3 秒和段间切换放提示音,靠耳朵就能跟上节奏;提示音关掉之后画面依然会变色和翻数字,戴耳机不方便的场合也能用。

三是对比不同间歇方案的实际总量。同样是「做 8 轮」,2:1 的 30/15 和 1:2 的 20/40 在总训练时间上差了一倍多。正文里的对照表把 16 组常见方案的训练总时长、休息总时长和全程时长都算好,排课时不用再手算。

四是让 Tabata 这类固定方案还原准确。经典 Tabata 是 20 秒全力、10 秒休息、重复 8 轮,合计 4 分钟,其中包含最后一轮之后的休息。本工具默认跳过末轮休息,所以直接填 20/10/8 会得到 3 分 50 秒,差的那 10 秒正好是一个休息段——勾上「结束后保留末轮休息」就与原始口径一致。

本页不做这些事:不喊动作口令、不统计次数与重量、不保存训练历史、不做心率区间提示。要记录每天练没练,用页面底部的「习惯打卡」;要看某段时间花在哪,用「时间追踪器」。

分段计时原理:链式截止时刻、单调时钟与振荡器提示音

计时内核只有一行读数:performance.now()。它按 W3C High Resolution Time Level 2 规范返回单调递增的毫秒浮点数,只会往前走,遇到系统对时也不会跳。常见的替代写法是把阶段时长累加进一个计数器,每 100 毫秒加一次,这种写法在页面被切到后台时会出错——浏览器会把后台标签页的定时器节流到最快 1000 毫秒一次,30 秒的训练段能被拉成好几分钟。

关键设计是「链式截止时刻」。每一段不是记「已经跑了多久」,而是记一个绝对的截止时间戳:第一段截止在 start + 准备秒数,第二段截止在第一段截止 + 训练秒数,依次往后推。每一帧只做一次比较,now >= 截止时刻 就切段。这样即使某一帧因为卡顿晚了 200 毫秒才切,下一段的截止时间仍然从前一段的原定时刻往后排,整场 350 秒不会因为几十次小延迟累积成 355 秒。若写成「切段时以当前时间为新起点」,每次切换都会把该帧的误差吃进总时长,8 轮下来能多出好几秒。

刷新用 requestAnimationFrame,目的不是省电,而是让计时与显示解耦。计时只依赖时间戳相减,和帧率无关;60 Hz 屏幕上每秒检查 60 次,120 Hz 屏幕上检查 120 次,结果一样。剩余秒数用 Math.ceil 向上取整:剩 0.2 秒时显示 1 而不是 0,避免数字在阶段真正结束前就归零。

提示音来自 Web Audio 的振荡器。每次发声都现场建一个 OscillatorNode(正弦波)和一个 GainNode,增益包络在前 5 毫秒线性升到 0.18、在段尾线性降回 0,两端都做了斜坡,所以听不到「咔」的开头爆音。三个阶段用三个频率区分:训练开始 880 Hz(A5)、休息开始 440 Hz(A4)、倒数 3 秒短哔 660 Hz,频率遵循十二平均律,880 恰好是 440 的两倍频。注意 AudioContext 必须在用户操作之后创建或 resume(),这是浏览器的自动播放策略要求的,所以这个 HIIT间隔训练计时器把音频上下文的创建放在「开始训练」和「试听提示音」的点击处理里。

参数为什么取这些默认值。训练 30 秒、休息 15 秒是 2:1 的常见配比,既有足够强度又留出不完全恢复的间隙;轮数 8 与 Tabata 的原始设计一致,一轮 45 秒、8 轮约 6 分钟,普通人能完整做完。准备倒计时给 5 秒是留出放下手机、站好位置的时间,不需要可以填 0。休息时长允许填 0,此时训练段首尾相接,变成一组连续训练。

完整示例(数值仅作演示)

下面用页面打开时的默认值在这个 HIIT间隔训练计时器里跑一遍。示例条件与默认值完全一致:准备 5 秒、训练 30 秒、休息 15 秒、8 轮、跳过末轮休息。按链式截止时刻铺开的阶段序列是:

把同一组参数改成经典 Tabata(准备 0、训练 20、休息 10、8 轮),跳过末轮休息是 0 + 160 + 70 = 230 秒(3:50);勾上「结束后保留末轮休息」变成 0 + 160 + 80 = 240 秒(4:00),与 1996 年 Tabata 研究里的原始方案完全对上。两者只差一个休息段的 10 秒,也正是最容易被人忽略的地方。

常见间歇方案与总时长对照表

下表按「跳过末轮休息」的口径逐个算出 16 组常用方案的总量,准备时间一律按 5 秒计(Tabata 两行按原始口径取 0 秒)。表里所有数字都由页面里的复算脚本按 准备 + 轮数 × 训练 + (轮数 − 1) × 休息 算出,可以直接拿去排课。

方案训练 / 休息轮数训练合计休息合计全程
Tabata 经典20 / 1082:401:103:50
Tabata 含末轮20 / 1082:401:204:00
默认 HIIT30 / 1584:001:455:50
30 / 30 × 1030 / 30105:004:309:35
40 / 20 × 840 / 2085:202:207:45
45 / 15 × 1045 / 15107:302:159:50
20 / 40 × 620 / 4062:003:205:25
60 / 60 × 560 / 6055:004:009:05
30 / 90 × 630 / 9063:007:3010:35
15 / 15 × 1215 / 15123:002:455:50
50 / 10 × 1050 / 10108:201:309:55
30 / 30 × 830 / 3084:003:307:35
25 / 5 × 1225 / 5125:000:556:00
30 / 20 × 1030 / 20105:003:008:05
60 / 30 × 860 / 3088:003:3011:35
20 / 20 × 1520 / 20155:004:409:45

挑方案时先看训练合计而不是轮数:同样是 8 轮,20/10 只有 2 分 40 秒的工作量,40/20 有 5 分 20 秒;再看休息合计,20/40 的休息时间比训练时间还长,这一组实际更接近低强度的间歇恢复,适合刚开始接触间歇训练的人。

输入范围、边界与舍入

常见问题

为什么不用 setInterval 每秒减一?

因为定时器会被浏览器节流。页面切到后台后,后台标签页的 setInterval 最小间隔会被抬到 1000 毫秒,一串「每秒减一」的累加会越减越慢,30 秒的训练段可能被拉成好几分钟;而按 performance.now() 的绝对截止时刻判断,无论中间漏了多少次检查,时间一到就切段。这也是这个 HIIT间隔训练计时器把计时和刷新彻底分开的原因。

点开始之后没有声音,是怎么回事?

多半是自动播放策略拦下了。浏览器要求页面在用户手势之后才允许播放音频,如果只是刷新页面、没有点击过任何按钮就调用了播放接口,音频上下文会停在 suspended 状态。解决办法就是点一下「试听提示音」或「开始训练」,有了一次真实点击之后声音就正常了。另外手机静音开关、浏览器标签页被静音也会导致无声。

训练到一半切去看别的页面,回来时间还准吗?

时间准,声音不一定。截止时刻记的是绝对时间戳,切回来时工具读一次 performance.now(),把已经过期的阶段一次性跳过,直接落到当前应该在的那一段,总时长不会因为后台暂停而变长。但后台期间 rAF 不运行,那些本该响的提示音不会补发,所以可能出现「切回来发现已经到第 4 轮休息了」的情况,建议练的时候让页面保持在前台。

最后一轮训练完为什么直接结束了,不再休息一次?

这是默认行为,可以用勾选框改。训练结束后紧接着进入休息,练完又不会再做一组,那段休息对训练本身没有意义,跳过可以让整套流程干净收尾。经典 Tabata 的原始方案口径是包含末轮休息的 4 分钟(8 × (20 + 10) = 240 秒),本工具默认跳过末轮得到 3 分 50 秒,想完全对齐就勾上「结束后保留末轮休息」。

三种提示音分别代表什么?

训练开始是 880 Hz 的较高音,休息开始是 440 Hz 的较低音,倒数 3 秒各有一次 660 Hz 的短哔,全部完成时是三声连续的高音。频率都取自十二平均律,880 是 440 的两倍频,两个音听起来是同一个音名的不同八度,容易分辨;每段声音的开头和结尾都加了 5 毫秒的增益斜坡,避免出现爆音。

休息时长填 0 会怎样?

休息段会被整段跳过,训练段首尾相接,等于连续做指定轮数。摘要区的「休息合计」会显示 0:00,「阶段数」也会相应减少——8 轮、准备 5 秒的方案会从 16 段变成 9 段。这种用法适合本来就不需要间歇的动作,或者想先用连续训练摸一次底再切回间歇节奏。

改参数会打断正在跑的计时吗?

不会。阶段序列在点「开始训练」的那一刻就已经按当时的参数固定下来,中途改输入框只刷新下方的方案摘要,正在跑的这组不受影响。想让新参数生效,点「重置」之后再点「开始训练」。这样做是为了避免练到第 5 轮被改动打乱节奏,也避免出现「轮数改成 3,但已经跑到第 6 轮」的错乱。

方案会被保存下来吗?关掉页面会不会丢?

不会保存。参数只存在当前页面的输入框里,刷新或关闭就回到默认的 5 / 30 / 15 / 8。这是刻意的:本页不写浏览器存储,也不发任何网络请求,所以同一台电脑上不会留下训练记录,也不会影响别人打开这个页面时看到的默认值。常用方案建议直接写在纸上或手机备忘里,照着填一遍很快。

相关工具