From 593d1aea209503f36a0b37673fc0ce0ad85ef67f Mon Sep 17 00:00:00 2001 From: elpatron Date: Fri, 29 May 2026 17:44:31 +0200 Subject: [PATCH] fix: Memory-Leak bei PWA-Update-Checks durch Cleanup beheben. Entfernt Listener und Intervalle beim erneuten SW-Register und beim Unmount des Hooks. Co-authored-by: Cursor --- client/src/hooks/usePwaUpdate.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/client/src/hooks/usePwaUpdate.ts b/client/src/hooks/usePwaUpdate.ts index 6c9408e..206387e 100644 --- a/client/src/hooks/usePwaUpdate.ts +++ b/client/src/hooks/usePwaUpdate.ts @@ -1,34 +1,51 @@ +import { useEffect, useRef } from 'react' import { useRegisterSW } from 'virtual:pwa-register/react' const UPDATE_CHECK_INTERVAL_MS = 60 * 60 * 1000 -function scheduleUpdateChecks(registration: ServiceWorkerRegistration) { +function scheduleUpdateChecks(registration: ServiceWorkerRegistration): () => void { const checkForUpdate = () => { registration.update().catch(() => {}) } - document.addEventListener('visibilitychange', () => { + const onVisibilityChange = () => { if (document.visibilityState === 'visible') { checkForUpdate() } - }) + } - window.setInterval(checkForUpdate, UPDATE_CHECK_INTERVAL_MS) + document.addEventListener('visibilitychange', onVisibilityChange) + const intervalId = window.setInterval(checkForUpdate, UPDATE_CHECK_INTERVAL_MS) + + return () => { + document.removeEventListener('visibilitychange', onVisibilityChange) + window.clearInterval(intervalId) + } } export function usePwaUpdate() { + const cleanupRef = useRef<(() => void) | null>(null) + const { needRefresh: [needRefresh], updateServiceWorker } = useRegisterSW({ immediate: true, onRegisteredSW(_swUrl: string, registration: ServiceWorkerRegistration | undefined) { - if (registration) { - scheduleUpdateChecks(registration) - } + if (!registration) return + + cleanupRef.current?.() + cleanupRef.current = scheduleUpdateChecks(registration) } }) + useEffect(() => { + return () => { + cleanupRef.current?.() + cleanupRef.current = null + } + }, []) + const updateApp = async () => { await updateServiceWorker(true) }