I'm building simple web timer to calculate time working on tasks. Say, I have a 5 min timer and when time is up, I receive a notification.
I build it storing the time in state. But when the tab (Chrome) is inactive, because I'm actually working, the time throttle and gather some delay. (Chrome does that to conserve memory).
import React, { useEffect } from "react";
import { useFinishSession } from "../../hooks/useFinishSession";
const TimerIsActive = ({ setTimer, timerState, isActive }) => {
const { seconds, minutes, initialSeconds, initialMinutes } = timerState;
const { decreaseSeconds, decreaseMinutes, setSessionMinutes, setSessionSeconds } = setTimer;
const { finishSession, loading, error } = useFinishSession();
useEffect(() => {
let interval: NodeJS.Timer;
// reduce seconds and minutes by 1
if (isActive) {
interval = setInterval(() => {
if (seconds > 0) {
decreaseSeconds();
}
// when timer is finised, restart
if (seconds === 0 && minutes === 0) {
finishSession();
setSessionMinutes(initialMinutes);
setSessionSeconds(initialSeconds);
clearInterval(interval);
}
if (seconds === 0) {
decreaseMinutes();
}
}, 1000);
return () => clearInterval(interval);
}
}, [isActive, seconds, minutes]);
return null;
};
export default TimerIsActive;
How I go around that?
Here'are the solutions I'm contemplating:
Instead of storing the time in state, I will store the "start time" using a new Date() and calculate the difference every second to get an accurate time. (difference in seconds) --> my main concern with this approach is that the time only "correct" when the tab regain "focus". Hence, the notification won't fire "in time" when the timer is over.
Using service worker to calculate the time in the background.
What is the best options?
Similar question: Countdown timer 'delays' when tab is inactive?