Tengo una aplicación de reacción (nextjs) y muestro un código QR que se actualiza cada 5 segundos y un reloj que se actualiza cada 1 segundo. Además, agregué un trabajador de servicio para habilitar PWA y soporte fuera de línea.
Después de ejecutarlo durante un par de horas, o incluso días, de la nada, la aplicación se congela y ya no se actualiza.
Si es relevante, sucede en dispositivos móviles (Android), ¿quizás haya algo con el modo de ahorro de energía o algo así? ¡Incluso si tiro hacia abajo para actualizar, la aplicación de reacción no cambia! Lo único es salir de Chrome y luego volver a abrir.
Realmente no tengo idea de cuál podría ser la causa del problema.
El uso de RAM parece ser el mismo todo el tiempo:
No hay llamadas de red, todo es local, este es el ejemplo de la función de reloj que uso:
useEffect(() => { const interval = setInterval(() => { setTime(new Date()); }, 1000); return () => { clearInterval(interval); }; }, []);La función de intervalo que uso para el código QR es:
useEffect(() => { const interval = setInterval(() => { setOptions((prev) => ({ ...prev, data: generateQrCodeString(), })); }, 5000); return () => { clearInterval(interval); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []);Uso esta librería qrcode: https://www.npmjs.com/package/qr-code-styling
¿Alguien tiene alguna sugerencia? ¡Agradezco cualquier ayuda!
Probé el gancho useInterval desde aquí https://usehooks-ts.com/react-hook/use-interval y parece estar funcionando mejor, pero después de un par de horas/días, todavía se congela.
Código actualizado:
useInterval(() => { setTime(new Date()); }, 1000); useInterval(() => { setOptions((prev) => ({ ...prev, data: generateQrCodeString(), })); }, 5000);Intente eliminar el pwa y verifique si todavía se congela o no. Para mí, eran encabezados de control de caché con algunos valores de almacenamiento en caché (para imágenes), todo lo que hice fue configurar el control de caché en 0 y dejar que pwa maneje el almacenamiento en caché por sí mismo.
Los ServiceWorkers están diseñados específicamente para ser de corta duración. El navegador puede cancelar el trabajador del servicio en cualquier momento.
Básicamente, no puede usar setInterval o setTimeout de manera confiable en un trabajador de servicio. La forma admitida de mantener vivo a un trabajador del servicio es pasar una promesa de waitUntil/respondWith , pero incluso entonces el navegador puede agotar el tiempo de la promesa y terminar el trabajador.
Más sobre waitUnitl
Entonces, según su explicación, lo que está sucediendo es que está atrapado en un bucle infinito con el método setInterval.
Puede lograr lo que quería hacer sin ganchos de reacción (useEffect o useInterval). Compruebe el código de abajo si le ayudará.
let seconds = 5; const interval = setInterval(() => { seconds = seconds - 1; console.log(seconds); if(seconds <=0){ clearInterval(interval); } }, 1000);