fix(pagespeed): poll for results after async check trigger
Backend now returns 202 immediately. Frontend polls every 5s for up to 2 minutes until new results appear, then shows success toast.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useAuth } from '@/lib/auth/context'
|
import { useAuth } from '@/lib/auth/context'
|
||||||
import { useEffect, useState } 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, type PageSpeedCheck, type AuditSummary } from '@/lib/api/pagespeed'
|
||||||
@@ -116,15 +116,47 @@ 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 stopPolling = useCallback(() => {
|
||||||
|
if (pollRef.current) {
|
||||||
|
clearInterval(pollRef.current)
|
||||||
|
pollRef.current = null
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// * Clean up polling on unmount
|
||||||
|
useEffect(() => () => stopPolling(), [stopPolling])
|
||||||
|
|
||||||
const handleRunCheck = async () => {
|
const handleRunCheck = async () => {
|
||||||
setRunning(true)
|
setRunning(true)
|
||||||
try {
|
try {
|
||||||
await triggerPageSpeedCheck(siteId)
|
await triggerPageSpeedCheck(siteId)
|
||||||
mutateLatest()
|
toast.success('PageSpeed check started — results will appear in 30-60 seconds')
|
||||||
toast.success('PageSpeed check complete')
|
|
||||||
|
// * Poll every 5s for up to 2 minutes until new results appear
|
||||||
|
const startedAt = Date.now()
|
||||||
|
const initialCheckedAt = latestChecks?.[0]?.checked_at
|
||||||
|
|
||||||
|
stopPolling()
|
||||||
|
pollRef.current = setInterval(async () => {
|
||||||
|
const elapsed = Date.now() - startedAt
|
||||||
|
if (elapsed > 120_000) {
|
||||||
|
stopPolling()
|
||||||
|
setRunning(false)
|
||||||
|
toast.error('Check is taking longer than expected. Results will appear when ready.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const freshData = await mutateLatest()
|
||||||
|
const freshCheckedAt = freshData?.[0]?.checked_at
|
||||||
|
if (freshCheckedAt && freshCheckedAt !== initialCheckedAt) {
|
||||||
|
stopPolling()
|
||||||
|
setRunning(false)
|
||||||
|
toast.success('PageSpeed check complete')
|
||||||
|
}
|
||||||
|
}, 5000)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
toast.error(err?.message || 'Failed to run check')
|
toast.error(err?.message || 'Failed to start check')
|
||||||
} finally {
|
|
||||||
setRunning(false)
|
setRunning(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,17 +75,8 @@ export async function getPageSpeedCheck(siteId: string, checkId: string): Promis
|
|||||||
return apiRequest<PageSpeedCheck>(`/sites/${siteId}/pagespeed/checks/${checkId}`)
|
return apiRequest<PageSpeedCheck>(`/sites/${siteId}/pagespeed/checks/${checkId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function triggerPageSpeedCheck(siteId: string): Promise<PageSpeedCheck[]> {
|
// * Triggers an async PageSpeed check. Returns immediately (202).
|
||||||
// * PSI checks take 10-30s per strategy (mobile + desktop sequential = up to 60s)
|
// * Caller should poll getPageSpeedLatest() for results.
|
||||||
const controller = new AbortController()
|
export async function triggerPageSpeedCheck(siteId: string): Promise<void> {
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 120_000)
|
await apiRequest(`/sites/${siteId}/pagespeed/check`, { method: 'POST' })
|
||||||
try {
|
|
||||||
const res = await apiRequest<{ checks: PageSpeedCheck[] }>(`/sites/${siteId}/pagespeed/check`, {
|
|
||||||
method: 'POST',
|
|
||||||
signal: controller.signal,
|
|
||||||
})
|
|
||||||
return res?.checks ?? []
|
|
||||||
} finally {
|
|
||||||
clearTimeout(timeoutId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user