Browse Source

make note feeds more performant

imwald
Silberengel 4 months ago
parent
commit
156af22eee
  1. 16
      src/components/NoteCard/index.tsx
  2. 10
      src/components/NoteList/index.tsx
  3. 19
      src/components/Profile/ProfileTimeline.tsx

16
src/components/NoteCard/index.tsx

@ -3,11 +3,11 @@ import { isMentioningMutedUsers } from '@/lib/event' @@ -3,11 +3,11 @@ import { isMentioningMutedUsers } from '@/lib/event'
import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import { useMuteList } from '@/providers/MuteListProvider'
import { Event, kinds } from 'nostr-tools'
import { useMemo } from 'react'
import { memo, useMemo } from 'react'
import MainNoteCard from './MainNoteCard'
import RepostNoteCard from './RepostNoteCard'
export default function NoteCard({
const NoteCard = memo(function NoteCard({
event,
className,
filterMutedNotes = true
@ -35,7 +35,17 @@ export default function NoteCard({ @@ -35,7 +35,17 @@ export default function NoteCard({
)
}
return <MainNoteCard event={event} className={className} />
}
}, (prevProps, nextProps) => {
// Custom comparison function for memo
return (
prevProps.event.id === nextProps.event.id &&
prevProps.event.created_at === nextProps.event.created_at &&
prevProps.className === nextProps.className &&
prevProps.filterMutedNotes === nextProps.filterMutedNotes
)
})
export default NoteCard
export function NoteCardLoadingSkeleton() {
return (

10
src/components/NoteList/index.tsx

@ -80,6 +80,14 @@ const NoteList = forwardRef( @@ -80,6 +80,14 @@ const NoteList = forwardRef(
const bottomRef = useRef<HTMLDivElement | null>(null)
const topRef = useRef<HTMLDivElement | null>(null)
// Memoize subRequests serialization to avoid expensive JSON.stringify on every render
const subRequestsKey = useMemo(() => {
return JSON.stringify(subRequests.map(req => ({
urls: [...req.urls].sort(), // Create a copy before sorting to avoid mutation
filter: req.filter
})))
}, [subRequests])
const shouldHideEvent = useCallback(
(evt: Event) => {
const pinnedEventHexIdSet = new Set()
@ -252,7 +260,7 @@ const NoteList = forwardRef( @@ -252,7 +260,7 @@ const NoteList = forwardRef(
return () => {
promise.then((closer) => closer())
}
}, [JSON.stringify(subRequests), refreshCount, showKinds])
}, [subRequestsKey, refreshCount, showKinds])
useEffect(() => {
const options = {

19
src/components/Profile/ProfileTimeline.tsx

@ -92,12 +92,19 @@ const ProfileTimeline = forwardRef< @@ -92,12 +92,19 @@ const ProfileTimeline = forwardRef<
if (!searchQuery.trim()) {
return eventsFilteredByKind
}
const query = searchQuery.toLowerCase()
return eventsFilteredByKind.filter(
(event) =>
event.content.toLowerCase().includes(query) ||
event.tags.some((tag) => tag.length > 1 && tag[1]?.toLowerCase().includes(query))
)
// Pre-compute lowercase query once
const query = searchQuery.toLowerCase().trim()
// Pre-compute lowercase content and tags for each event to avoid repeated conversions
return eventsFilteredByKind.filter((event) => {
const contentLower = event.content.toLowerCase()
if (contentLower.includes(query)) return true
// Only check tags if content doesn't match
return event.tags.some((tag) => {
if (tag.length <= 1) return false
const tagValue = tag[1]
return tagValue && tagValue.toLowerCase().includes(query)
})
})
}, [eventsFilteredByKind, searchQuery])
// Reset showCount when filters change

Loading…
Cancel
Save