perf: virtualize req viewer

This commit is contained in:
Alejandro Gómez
2025-12-12 22:49:39 +01:00
parent 54cff0af9b
commit 53c07fb4a8
3 changed files with 28 additions and 4 deletions

11
package-lock.json generated
View File

@@ -33,6 +33,7 @@
"react-medium-image-zoom": "^5.4.0",
"react-mosaic-component": "^6.1.1",
"react-router": "^7.1.0",
"react-virtuoso": "^4.17.0",
"remark-gfm": "^4.0.1",
"rxjs": "^7.8.1",
"tailwind-merge": "^2.5.5"
@@ -8019,6 +8020,16 @@
}
}
},
"node_modules/react-virtuoso": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.17.0.tgz",
"integrity": "sha512-od3pi2v13v31uzn5zPXC2u3ouISFCVhjFVFch2VvS2Cx7pWA2F1aJa3XhNTN2F07M3lhfnMnsmGeH+7wZICr7w==",
"license": "MIT",
"peerDependencies": {
"react": ">=16 || >=17 || >= 18 || >= 19",
"react-dom": ">=16 || >=17 || >= 18 || >=19"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",

View File

@@ -41,6 +41,7 @@
"react-medium-image-zoom": "^5.4.0",
"react-mosaic-component": "^6.1.1",
"react-router": "^7.1.0",
"react-virtuoso": "^4.17.0",
"remark-gfm": "^4.0.1",
"rxjs": "^7.8.1",
"tailwind-merge": "^2.5.5"

View File

@@ -1,4 +1,5 @@
import { useState } from "react";
import { useState, memo } from "react";
import { Virtuoso } from "react-virtuoso";
import {
ChevronDown,
ChevronRight,
@@ -14,6 +15,12 @@ import { FeedEvent } from "./nostr/Feed";
import { KindBadge } from "./KindBadge";
import type { NostrFilter } from "@/types/nostr";
// Memoized FeedEvent to prevent unnecessary re-renders during scroll
const MemoizedFeedEvent = memo(
FeedEvent,
(prev, next) => prev.event.id === next.event.id,
);
interface ReqViewerProps {
filter: NostrFilter;
relays?: string[];
@@ -240,9 +247,14 @@ export default function ReqViewer({
Waiting for events...
</div>
)}
{events.map((event) => (
<FeedEvent key={event.id} event={event} />
))}
{events.length > 0 && (
<Virtuoso
style={{ height: "100%" }}
data={events}
computeItemKey={(_index, event) => event.id}
itemContent={(_index, event) => <MemoizedFeedEvent event={event} />}
/>
)}
</div>
</div>
);