DropsTheTicksBro

HTML

<main>
    <h1>setInterval tick test</h1>
      <p class="intro">
          Start the timer, block the event loop, and see whether missed interval
              ticks fire in a burst.
                </p>

                  <section>
                      <h2>Live counts</h2>
                          <div class="stats">
                                <div><small>Ticks fired</small><b id="ticks">0</b></div>
                                      <div><small>Seconds elapsed</small><b id="elapsed">0</b></div>
                                            <div><small>Ticks lost</small><b id="lost">0</b></div>
                                                  <div><small>Condition fired</small><b id="fired">0</b></div>
                                                      </div>
                                                        </section>

                                                          <section>
                                                              <h2>Last 30 seconds</h2>
                                                                  <canvas id="strip"></canvas>
                                                                      <div class="key"><span>−30s</span><span>gap, not cluster</span><span>now</span></div>
                                                                        </section>

                                                                          <section>
                                                                              <h2>Controls</h2>
                                                                                  <div class="buttons">
                                                                                        <button id="start">Start timer</button>
                                                                                              <button id="block" disabled>Block loop 10s</button>
                                                                     ...

CSS

*{box-sizing:border-box}
body{
  margin:0;
    padding:30px 18px;
      background:#101219;
        color:#e4e2db;
          font:14px/1.5 ui-monospace,monospace
          }
          main{max-width:760px;margin:auto}
          h1{font-size:16px;text-transform:uppercase;letter-spacing:.12em}
          h2{
            margin:0 0 14px;
              color:#767c92;
                font-size:11px;
                  font-weight:400;
                    text-transform:uppercase;
                      letter-spacing:.15em
                      }
                      .intro,.note,.key,td:last-child{color:#767c92}
                      .intro{max-width:62ch;margin-bottom:28px}
                      section{
                        margin-bottom:18px;
                          padding:20px;
                            background:#171a24;
                              border:1px solid #262b39
                              }
                              .stats,.buttons,.key{display:flex;flex-wrap:wrap}
                              .stats{gap:28px}
                              .stats div{min-width:120px}
                              small{display:block;color:#767c92;text-transform:uppercase}
                              b{display:block;font-size:32px;font-weight:400}
                              .stats div:nth-child(1) b{color:#6aa6ff}
                              .stats div:nth-child(2) b{color:#f0a830}
                              .stats div:nth-child(3) b{color:#ff6b5e}
                              canvas{
                                display:block;
                                  width:100%;
                                    height:68px;
                                      background:#0c0e14;
                                        border:1px solid #262b39
                                        }
                                        .key{justify-content:space-between;margin-top:7px;font-size:11px}
          ...

JavaScript

const $ = id => document.getElementById(id);
const ui = {
  ticks:$("ticks"), elapsed:$("elapsed"), lost:$("lost"), fired:$("fired"),
    strip:$("strip"), log:$("log"), start:$("start"),
      block:$("block"), alert:$("alert"), reset:$("reset")
      };

      let started = 0, timer = 0, ticks = 0, fired = 0;
      let lastTick = 0, history = [];

      function elapsed() {
        return started ? Math.floor((Date.now() - started) / 1000) : 0;
        }

        function tick() {
          const now = Date.now();
            ticks++;
              history.push({at:now, gap:lastTick ? now-lastTick : 0});
                lastTick = now;

                  if (now-started < 60000) fired++;
                    if (history.length > 400) history.shift();

                      render();
                      }

                      function render() {
                        const seconds = elapsed();

                          ui.ticks.textContent = ticks;
                            ui.elapsed.textContent = seconds;
                              ui.lost.textContent = Math.max(0, seconds-ticks);
                                ui.fired.textContent = fired;

                                  ui.log.innerHTML = history.length
                                      ? history.slice(-10).reverse().map((item,i) => {
                                              const time = new Date(item.at).toLocaleTimeString([], {
                                                        hour12:false,
                                                                  hour:"2-digit",
                                                                            minute:"2-digit",
                                                                                      second:"2-digit",
                                                                                                fractionalSecondDigits:3
                                                    ...