fix(pagespeed): poll silently without triggering SWR re-renders
Use direct API fetch for polling instead of mutateLatest() which was causing the page to flicker and clear data every 5 seconds. SWR cache is only updated once when new results arrive.
This commit is contained in:
@@ -4,7 +4,7 @@ import { useAuth } from '@/lib/auth/context'
|
|||||||
import { useEffect, useState, useRef, useCallback } from 'react'
|
import { useEffect, useState, useRef, useCallback } from 'react'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import { useSite, usePageSpeedConfig, usePageSpeedLatest, usePageSpeedHistory } from '@/lib/swr/dashboard'
|
import { useSite, usePageSpeedConfig, usePageSpeedLatest, usePageSpeedHistory } from '@/lib/swr/dashboard'
|
||||||
import { updatePageSpeedConfig, triggerPageSpeedCheck, type PageSpeedCheck, type AuditSummary } from '@/lib/api/pagespeed'
|
import { updatePageSpeedConfig, triggerPageSpeedCheck, getPageSpeedLatest, type PageSpeedCheck, type AuditSummary } from '@/lib/api/pagespeed'
|
||||||
import { toast, Button } from '@ciphera-net/ui'
|
import { toast, Button } from '@ciphera-net/ui'
|
||||||
import ScoreGauge from '@/components/pagespeed/ScoreGauge'
|
import ScoreGauge from '@/components/pagespeed/ScoreGauge'
|
||||||
import {
|
import {
|
||||||
@@ -116,7 +116,6 @@ export default function PageSpeedPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// * Trigger a manual PageSpeed check
|
// * Trigger a manual PageSpeed check
|
||||||
// * Poll for results after triggering an async check
|
|
||||||
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
|
const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)
|
||||||
const stopPolling = useCallback(() => {
|
const stopPolling = useCallback(() => {
|
||||||
if (pollRef.current) {
|
if (pollRef.current) {
|
||||||
@@ -125,7 +124,6 @@ export default function PageSpeedPage() {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// * Clean up polling on unmount
|
|
||||||
useEffect(() => () => stopPolling(), [stopPolling])
|
useEffect(() => () => stopPolling(), [stopPolling])
|
||||||
|
|
||||||
const handleRunCheck = async () => {
|
const handleRunCheck = async () => {
|
||||||
@@ -134,25 +132,29 @@ export default function PageSpeedPage() {
|
|||||||
await triggerPageSpeedCheck(siteId)
|
await triggerPageSpeedCheck(siteId)
|
||||||
toast.success('PageSpeed check started — results will appear in 30-60 seconds')
|
toast.success('PageSpeed check started — results will appear in 30-60 seconds')
|
||||||
|
|
||||||
// * Poll every 5s for up to 2 minutes until new results appear
|
// * Poll silently without triggering SWR re-renders.
|
||||||
const startedAt = Date.now()
|
// * Fetch latest directly and only update SWR cache once when new data arrives.
|
||||||
const initialCheckedAt = latestChecks?.[0]?.checked_at
|
const initialCheckedAt = latestChecks?.[0]?.checked_at
|
||||||
|
const startedAt = Date.now()
|
||||||
|
|
||||||
stopPolling()
|
stopPolling()
|
||||||
pollRef.current = setInterval(async () => {
|
pollRef.current = setInterval(async () => {
|
||||||
const elapsed = Date.now() - startedAt
|
if (Date.now() - startedAt > 120_000) {
|
||||||
if (elapsed > 120_000) {
|
|
||||||
stopPolling()
|
stopPolling()
|
||||||
setRunning(false)
|
setRunning(false)
|
||||||
toast.error('Check is taking longer than expected. Results will appear when ready.')
|
toast.error('Check is taking longer than expected. Results will appear when ready.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const freshData = await mutateLatest()
|
try {
|
||||||
const freshCheckedAt = freshData?.[0]?.checked_at
|
const fresh = await getPageSpeedLatest(siteId)
|
||||||
if (freshCheckedAt && freshCheckedAt !== initialCheckedAt) {
|
if (fresh?.[0]?.checked_at && fresh[0].checked_at !== initialCheckedAt) {
|
||||||
stopPolling()
|
stopPolling()
|
||||||
setRunning(false)
|
setRunning(false)
|
||||||
toast.success('PageSpeed check complete')
|
mutateLatest() // * Single SWR revalidation when new data is ready
|
||||||
|
toast.success('PageSpeed check complete')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// * Silent — keep polling
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
Reference in New Issue
Block a user