Browse Source

fix slow-loading profiles

imwald
Silberengel 1 month ago
parent
commit
8f5e140247
  1. 62
      src/hooks/useFetchProfile.tsx

62
src/hooks/useFetchProfile.tsx

@ -442,16 +442,20 @@ export function useFetchProfile(id?: string, skipCache = false) { @@ -442,16 +442,20 @@ export function useFetchProfile(id?: string, skipCache = false) {
}
}
// CRITICAL: Early exit if already processing this exact pubkey - prevents infinite loops
// This check must happen FIRST, before any other logic
// Set processingPubkeyRef IMMEDIATELY after extraction to prevent race conditions
// Skip only when this pubkey already has an in-flight fetch (global dedupe + local flag).
// Do **not** return merely because processingPubkeyRef matches: after a failed or timed-out
// fetch, deps can change (e.g. noteFeed.version) while ref is still set — returning here
// left the hook stuck forever (blank profile / 404 until hard reload).
if (extractedPubkey) {
if (processingPubkeyRef.current === extractedPubkey) {
// Silently exit - no logging to reduce noise
return
const sharedPromise = globalFetchPromises.get(extractedPubkey)
const busy =
Boolean(sharedPromise) ||
globalFetchingPubkeys.has(extractedPubkey) ||
isFetching
if (busy) return
if (profile?.pubkey === extractedPubkey && !profile.batchPlaceholder) return
}
// Mark that we're processing this pubkey IMMEDIATELY to prevent concurrent runs
// We'll clear it later if we early exit for other reasons
processingPubkeyRef.current = extractedPubkey
}
@ -505,6 +509,8 @@ export function useFetchProfile(id?: string, skipCache = false) { @@ -505,6 +509,8 @@ export function useFetchProfile(id?: string, skipCache = false) {
setTimeout(() => {
effectRunCountRef.current.delete(extractedPubkey)
}, 30000) // Clear after 30 seconds
processingPubkeyRef.current = null
if (isFetching) setIsFetching(false)
return
}
// Only increment if we're actually going to process
@ -727,28 +733,28 @@ export function useFetchProfile(id?: string, skipCache = false) { @@ -727,28 +733,28 @@ export function useFetchProfile(id?: string, skipCache = false) {
}, [id, skipCache, noteFeed?.version]) // checkProfile is memoized; noteFeed.version hydrates batch profiles
useEffect(() => {
// CRITICAL: Only use currentAccountProfile if it matches the pubkey we're looking for
// Use pubkey from the profile object to avoid reference equality issues
// Only update if we don't have a profile yet AND we're not currently processing
// CRITICAL FIX: Don't include profile in dependencies to prevent infinite loops
// We only read profile to check if it exists, we don't need to re-run when it changes
if (currentAccountProfile?.pubkey && pubkey && pubkey === currentAccountProfile.pubkey) {
// Only update if we don't have a profile yet (avoid unnecessary updates)
// Also check that we're processing this pubkey to prevent race conditions
if (!profile && processingPubkeyRef.current === pubkey) {
setProfile(currentAccountProfile)
setIsFetching(false)
// Clear interval if we got the profile from current account
if (checkIntervalRef.current) {
clearInterval(checkIntervalRef.current)
checkIntervalRef.current = null
}
// Clear run count since we have the profile
effectRunCountRef.current.delete(pubkey)
}
const acc = currentAccountProfile
const accPk = acc?.pubkey
if (!accPk || !id) return
const targetPk = userIdToPubkey(id)
if (targetPk.length !== 64 || !/^[0-9a-f]{64}$/i.test(targetPk)) return
if (targetPk !== accPk.toLowerCase()) return
const haveFullLocal =
profile?.pubkey === targetPk && !profile.batchPlaceholder
if (haveFullLocal) return
setProfile(acc)
setIsFetching(false)
setError(null)
processingPubkeyRef.current = targetPk
initializedPubkeysRef.current.add(targetPk)
if (checkIntervalRef.current) {
clearInterval(checkIntervalRef.current)
checkIntervalRef.current = null
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentAccountProfile?.pubkey, pubkey]) // Removed profile from dependencies to prevent infinite loops
effectRunCountRef.current.delete(targetPk)
}, [currentAccountProfile, id, profile])
return { isFetching, error, profile }
}

Loading…
Cancel
Save