Description
initEyeCareReminder() in eye-care-reminder.js:521 unconditionally creates a 1 Hz timer:
checkTimer = createTimer(evaluateReminder, 1000) // CHECK_INTERVAL_MS = 1000
regardless of whether the feature is enabled. The default state is {enabled:false} (eye-care-reminder.js:90 and settings.js:1399), so every newly opened tab spawns a timer that wakes every second to read localStorage('eyeCareReminder'), call Date.now(), and run clearExpiredActiveReminder/syncVisibleElapsed/evaluateReminder, even though evaluateReminder immediately returns when !enabled.
VisibilityInterval does pause while hidden, but while any tab is visible the timer still burns CPU and I/O forever for a disabled feature. refreshEyeCareReminder() also ends with unconditional evaluateReminder() and never manages checkTimer lifecycle. The disabled path in evaluateReminder() (438–449) and clearActiveReminderState() (471–483) only stop countdownTimer, never call stopCheckTimer().
File
src/features/eye-care-reminder.js around line 521 (and 518 for refreshEyeCareReminder, 438 for disabled early return).
Reproduction
- Fresh profile — never enable Eye-care reminder (default disabled).
- Open 5 New Tab pages.
- Profile with DevTools Performance or add
console.log inside evaluateReminder.
- Observe ~5 wakeups/second even though the feature is off; each does
localStorage.getItem + JSON.parse. After 8 hours of idle visible tabs this is ~144k unnecessary wakeups per tab.
Expected: checkTimer should only be started when loadState().enabled === true and stopped when the state becomes disabled.
The sibling bug is pomodoro.js:476 where non-leader tabs poll via raw setInterval(reconcileTimerState, 1000) even when document.hidden === true (should use VisibilityInterval), compounding the waste with multiple tabs.
Suggested fix
Guard initEyeCareReminder and refreshEyeCareReminder to start checkTimer only when enabled, and call stopCheckTimer() immediately when state.enabled becomes false. For pomodoro, replace the raw setInterval with new VisibilityInterval.
Duplicate check
Searched existing issues: #701–#705 are all games perf, #706–#710 are feature requests. No existing issue mentions eye-care-reminder, checkTimer, or evaluation polling. Not a duplicate.
Category / Severity
Category: performance | Severity: medium (high waste at scale)
Verified: lines 521–526 show unconditional createTimer(evaluateReminder, 1000) with no guard on loadState().enabled; default state is {enabled:false}; disabled path never stops checkTimer.
Description
initEyeCareReminder()in eye-care-reminder.js:521 unconditionally creates a 1 Hz timer:regardless of whether the feature is enabled. The default state is
{enabled:false}(eye-care-reminder.js:90 and settings.js:1399), so every newly opened tab spawns a timer that wakes every second to readlocalStorage('eyeCareReminder'), callDate.now(), and runclearExpiredActiveReminder/syncVisibleElapsed/evaluateReminder, even thoughevaluateReminderimmediately returns when!enabled.VisibilityIntervaldoes pause while hidden, but while any tab is visible the timer still burns CPU and I/O forever for a disabled feature.refreshEyeCareReminder()also ends with unconditionalevaluateReminder()and never managescheckTimerlifecycle. The disabled path inevaluateReminder()(438–449) andclearActiveReminderState()(471–483) only stopcountdownTimer, never callstopCheckTimer().File
src/features/eye-care-reminder.jsaround line 521 (and 518 forrefreshEyeCareReminder, 438 for disabled early return).Reproduction
console.loginsideevaluateReminder.localStorage.getItem+JSON.parse. After 8 hours of idle visible tabs this is ~144k unnecessary wakeups per tab.Expected:
checkTimershould only be started whenloadState().enabled === trueand stopped when the state becomes disabled.The sibling bug is pomodoro.js:476 where non-leader tabs poll via raw
setInterval(reconcileTimerState, 1000)even whendocument.hidden === true(should useVisibilityInterval), compounding the waste with multiple tabs.Suggested fix
Guard
initEyeCareReminderandrefreshEyeCareReminderto startcheckTimeronly whenenabled, and callstopCheckTimer()immediately whenstate.enabledbecomes false. For pomodoro, replace the rawsetIntervalwithnew VisibilityInterval.Duplicate check
Searched existing issues: #701–#705 are all games perf, #706–#710 are feature requests. No existing issue mentions
eye-care-reminder,checkTimer, or evaluation polling. Not a duplicate.Category / Severity
Category: performance | Severity: medium (high waste at scale)
Verified: lines 521–526 show unconditional
createTimer(evaluateReminder, 1000)with no guard onloadState().enabled; default state is{enabled:false}; disabled path never stopscheckTimer.