Skip to content

~1ms busy-poll loop after the playhead passes the last timed word (and on null data-m mid-transcript) #263

Description

@maboa

Summary

(As of v2.6.2.) The next-tick interval derives from the next word's data-m (hyperaudio-lite.js:928-933):

let interval = 0;
if (this.wordArr[index]) {
  interval = this.wordArr[index].n.getAttribute('data-m') - this.currentTime * 1000;
}
this.timer = setTimeout(() => this.checkPlayHead(), interval + 1);

Once currentTime passes the final word, index === wordArr.length, wordArr[index] is undefined, so interval stays 0 and the loop re-arms every 1 ms (browser-clamped to ~4 ms after nesting depth 5 → ~250 wakeups/s, each an async getTime() promise plus an O(log n) binary search).

Failure scenario

Transcript ends before the audio (trailing music, untranscribed Q&A): ten minutes of outro ≈ 150k timer wakeups — sustained CPU/battery drain, silent. Also, getAttribute('data-m') returning null (attribute removed by an edit) coerces the subtraction to a negative interval → the same tight loop mid-transcript.

Fix

When wordArr[index] is missing, or the computed interval is ≤ 0 / NaN, fall back to a sane poll interval (e.g. 250 ms).

Found reviewing the copy vendored in hyperaudio-lite-editor / GliderMac (2026-07-11).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions