Skip to content

Commit 2fbf835

Browse files
committed
Remove redundant useProfileByUserId calls in VoteCommentRow: use avatars from comment data and avoid excessive profile lookups. Optimize useProfileByUserId with deduplication for concurrent requests.
1 parent 5ebbb0e commit 2fbf835

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

web/components/votes/vote-comments.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {Tooltip} from 'web/components/widgets/tooltip'
2424
import {UserLink} from 'web/components/widgets/user-link'
2525
import {useAdmin} from 'web/hooks/use-admin'
2626
import {useEvent} from 'web/hooks/use-event'
27-
import {useProfileByUserId} from 'web/hooks/use-profile'
2827
import {useUser} from 'web/hooks/use-user'
2928
import {api} from 'web/lib/api'
3029
import {firebaseLogin} from 'web/lib/firebase/users'
@@ -336,6 +335,10 @@ function VoteCommentThread(props: {
336335
)
337336
}
338337

338+
// Renders from the denormalized author columns on the comment row and fetches nothing. It used to
339+
// call useProfileByUserId for `pinned_url`, which on a thread of 28 comments meant 28 profile
340+
// lookups — 112 requests, all for the same handful of people — to slightly freshen an avatar the
341+
// comment row already carries. A stale avatar on an old comment is the right trade.
339342
const VoteCommentRow = memo(function VoteCommentRow(props: {
340343
comment: VoteComment
341344
choice: number | undefined
@@ -348,7 +351,6 @@ const VoteCommentRow = memo(function VoteCommentRow(props: {
348351
const ref = useRef<HTMLDivElement>(null)
349352
const [comment, setComment] = useState(props.comment)
350353
const {userUsername, userAvatarUrl, userId, hidden} = comment
351-
const profile = useProfileByUserId(userId)
352354
const t = useT()
353355

354356
useEffect(() => {
@@ -367,7 +369,7 @@ const VoteCommentRow = memo(function VoteCommentRow(props: {
367369
<Avatar
368370
username={userUsername}
369371
size={isParent ? 'sm' : '2xs'}
370-
avatarUrl={profile?.pinned_url ?? userAvatarUrl}
372+
avatarUrl={userAvatarUrl}
371373
/>
372374
{/* The spine starts at the bottom of the parent avatar rather than the top of the row.
373375
Avatar puts its className on the <img>, which is position:static, so a `z-10` there is

web/hooks/use-profile.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,29 @@ export const useProfileByUser = (user: User | undefined) => {
8282
return {profile, refreshProfile}
8383
}
8484

85+
// In-flight requests, keyed by user id. `usePersistentInMemoryState` already shares the *result*
86+
// between components asking for the same profile, but nothing stopped them all firing the request:
87+
// N components mounting together produced N identical lookups, and each lookup is four round trips
88+
// (profile plus interests, causes and work). Same idea as `useGetter`'s cache, one layer down.
89+
const profilePromises: Record<string, Promise<ProfileWithoutUser | null> | undefined> = {}
90+
8591
export const useProfileByUserId = (userId: string | undefined) => {
8692
const [profile, setProfile] = usePersistentInMemoryState<ProfileWithoutUser | undefined | null>(
8793
undefined,
8894
`profile-${userId}`,
8995
)
9096

9197
useEffect(() => {
92-
// console.debug('Refreshing profile in useProfileByUserId for', userId, profile);
93-
if (userId)
94-
getProfileRowWithFrontendSupabase(userId, db).then((profile) => {
95-
if (!profile) setProfile(null)
96-
else setProfile(profile)
97-
})
98+
if (!userId) return
99+
const pending =
100+
profilePromises[userId] ??
101+
(profilePromises[userId] = getProfileRowWithFrontendSupabase(userId, db).finally(() => {
102+
// Cleared once settled, so this dedupes concurrent callers without becoming a cache that
103+
// never refreshes — a later mount still refetches, as it did before.
104+
delete profilePromises[userId]
105+
}))
106+
107+
pending.then((profile) => setProfile(profile ?? null))
98108
}, [userId])
99109

100110
return profile

0 commit comments

Comments
 (0)