Marta programa frontend y lleva años usando la técnica pomodoro con aplicaciones que le pedían cuenta, le mandaban estadísticas por correo y querían saber en qué tarea estaba. Un martes a la hora de comer abrió Elffuss Code en el navegador y se puso a hacerse uno propio: una cuenta atrás, una lista de tareas y un sonido al acabar. Nada más.
La primera versión cabía en una pantalla:
let restantes = 25 * 60;
setInterval(() => { restantes--; pintar(); }, 1000);
La probó mirándola y funcionaba. Esa tarde la usó de verdad: arrancó el temporizador, se fue a la pestaña del repositorio y se puso a revisar una pull request. El aviso sonó cuando ella ya llevaba un rato pensando «esto tiene que estar a punto». Volvió a la pestaña y aún le quedaban casi seis minutos.
Lo que le preguntó a la IA
Pegó el código en el chat del IDE junto con la lista de tareas tal como la tenía, con los nombres de dos clientes y el título de un contrato que estaba revisando, y escribió: «¿por qué se retrasa cuando cambio de pestaña?».
La respuesta fue directa. Los navegadores frenan los temporizadores de las pestañas en segundo plano para ahorrar batería y CPU, y si la pestaña lleva un rato oculta los agrupan todavía más. setInterval no promete que la función se ejecute cada segundo, solo que no se ejecutará antes. Su código daba por hecho que cada llamada era un segundo exacto, y cada llamada que llegaba tarde se iba sumando al retraso.
Contar el tiempo en vez de contar los ticks
La IA le propuso cambiar la pregunta. En lugar de «¿cuántas veces me han llamado?», preguntar «¿cuánto falta para la hora de acabar?»:
- Al arrancar, guardar fin = performance.now() + duracion.
- En cada tick, calcular restantes = Math.max(0, Math.ceil((fin - performance.now()) / 1000)).
- Escuchar visibilitychange para repintar en cuanto la pestaña vuelve a estar visible, sin esperar al siguiente tick.
Marta preguntó por qué performance.now() y no Date.now(). La explicación también tenía sentido: el reloj del sistema puede moverse si se sincroniza o si alguien cambia la hora, y entonces el temporizador daría saltos. performance.now() solo avanza.
La IA también fue honesta con lo que el cambio no arregla: si el navegador frena mucho la pestaña, el sonido puede llegar un poco tarde. La diferencia es que ese retraso ya no se acumula. La cuenta es correcta cada vez que miras, y el desfase no crece a lo largo de la sesión. Para ella era suficiente.
La parte que no se ve
Para entender el fallo hizo falta pegar el código tal cual, con la lista de tareas reales dentro. Ni se le pasó por la cabeza limpiarla, y no tuvo que hacerlo: el modelo corre en la pestaña, sobre su propia GPU, así que los nombres de sus clientes no salieron de su equipo. Una herramienta pensada para no tener que darle a nadie tu lista de tareas tenía que construirse de la misma forma.
Ahora el temporizador vive en una pestaña fijada. Sin cuenta, sin estadísticas por correo y sonando cuando toca.
Abre Elffuss Code y construye tu propia herramienta pequeña: la IA corre en tu navegador, sin servidor y sin subir ni una línea de tu código.
Abrir Code →