improve timeline render performance

This commit is contained in:
hzrd149 2023-06-30 07:22:18 -05:00
parent c036a9a541
commit 1fbc6bfb96
5 changed files with 32 additions and 44 deletions

View File

@ -0,0 +1,23 @@
import React from "react";
import useSubject from "../hooks/use-subject";
import { TimelineLoader } from "../classes/timeline-loader";
import RepostNote from "./repost-note";
import { Note } from "./note";
const GenericNoteTimeline = React.memo(({ timeline }: { timeline: TimelineLoader }) => {
const notes = useSubject(timeline.timeline);
return (
<>
{notes.map((note) =>
note.kind === 6 ? (
<RepostNote key={note.id} event={note} maxHeight={1200} />
) : (
<Note key={note.id} event={note} maxHeight={1200} />
)
)}
</>
);
});
export default GenericNoteTimeline;

View File

@ -19,7 +19,6 @@ import { useAppTitle } from "../../hooks/use-app-title";
import { useReadRelayUrls } from "../../hooks/use-client-relays";
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
import { isReply } from "../../helpers/nostr-event";
import { Note } from "../../components/note";
import { CheckIcon, EditIcon, RelayIcon } from "../../components/icons";
import { useCallback, useEffect, useRef, useState } from "react";
import RelaySelectionModal from "./relay-selection-modal";
@ -27,7 +26,7 @@ import { NostrEvent } from "../../types/nostr-event";
import TimelineActionAndStatus from "../../components/timeline-action-and-status";
import IntersectionObserverProvider from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import useSubject from "../../hooks/use-subject";
import GenericNoteTimeline from "../../components/generric-note-timeline";
function EditableControls() {
const { isEditing, getSubmitButtonProps, getCancelButtonProps, getEditButtonProps } = useEditableControls();
@ -69,8 +68,6 @@ export default function HashTagView() {
{ eventFilter }
);
const events = useSubject(timeline.timeline);
const scrollBox = useRef<HTMLDivElement | null>(null);
const callback = useTimelineCurserIntersectionCallback(timeline);
@ -118,10 +115,8 @@ export default function HashTagView() {
</FormLabel>
</FormControl>
</Flex>
{events.map((event) => (
<Note key={event.id} event={event} maxHeight={600} />
))}
<GenericNoteTimeline timeline={timeline} />
<TimelineActionAndStatus timeline={timeline} />
</Flex>
</IntersectionObserverProvider>

View File

@ -1,6 +1,5 @@
import { Button, Flex, FormControl, FormLabel, Switch } from "@chakra-ui/react";
import { useSearchParams } from "react-router-dom";
import { Note } from "../../components/note";
import { isReply, truncatedId } from "../../helpers/nostr-event";
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
import { useUserContacts } from "../../hooks/use-user-contacts";
@ -9,13 +8,12 @@ import { useCallback, useContext, useRef } from "react";
import { PostModalContext } from "../../providers/post-modal-provider";
import { useReadRelayUrls } from "../../hooks/use-client-relays";
import { useCurrentAccount } from "../../hooks/use-current-account";
import RepostNote from "../../components/repost-note";
import RequireCurrentAccount from "../../providers/require-current-account";
import { NostrEvent } from "../../types/nostr-event";
import TimelineActionAndStatus from "../../components/timeline-action-and-status";
import IntersectionObserverProvider from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import useSubject from "../../hooks/use-subject";
import GenericNoteTimeline from "../../components/generric-note-timeline";
function FollowingTabBody() {
const account = useCurrentAccount()!;
@ -44,8 +42,6 @@ function FollowingTabBody() {
{ enabled: following.length > 0, eventFilter }
);
const events = useSubject(timeline.timeline);
const scrollBox = useRef<HTMLDivElement | null>(null);
const callback = useTimelineCurserIntersectionCallback(timeline);
@ -67,13 +63,8 @@ function FollowingTabBody() {
</FormLabel>
<Switch id="show-replies" isChecked={showReplies} onChange={onToggle} />
</FormControl>
{events.map((event) =>
event.kind === 6 ? (
<RepostNote key={event.id} event={event} maxHeight={600} />
) : (
<Note key={event.id} event={event} maxHeight={600} />
)
)}
<GenericNoteTimeline timeline={timeline} />
<TimelineActionAndStatus timeline={timeline} />
</Flex>

View File

@ -1,7 +1,6 @@
import { useCallback, useRef } from "react";
import { Flex, FormControl, FormLabel, Select, Switch, useDisclosure } from "@chakra-ui/react";
import { useSearchParams } from "react-router-dom";
import { Note } from "../../components/note";
import { unique } from "../../helpers/array";
import { isReply } from "../../helpers/nostr-event";
import { useAppTitle } from "../../hooks/use-app-title";
@ -9,9 +8,9 @@ import { useReadRelayUrls } from "../../hooks/use-client-relays";
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
import { NostrEvent } from "../../types/nostr-event";
import TimelineActionAndStatus from "../../components/timeline-action-and-status";
import useSubject from "../../hooks/use-subject";
import IntersectionObserverProvider from "../../providers/intersection-observer";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
import GenericNoteTimeline from "../../components/generric-note-timeline";
export default function GlobalTab() {
useAppTitle("global");
@ -42,8 +41,6 @@ export default function GlobalTab() {
{ eventFilter }
);
const events = useSubject(timeline.timeline);
const scrollBox = useRef<HTMLDivElement | null>(null);
const callback = useTimelineCurserIntersectionCallback(timeline);
@ -72,10 +69,8 @@ export default function GlobalTab() {
</FormLabel>
</FormControl>
</Flex>
{events.map((event) => (
<Note key={event.id} event={event} maxHeight={600} />
))}
<GenericNoteTimeline timeline={timeline} />
<TimelineActionAndStatus timeline={timeline} />
</Flex>
</IntersectionObserverProvider>

View File

@ -14,22 +14,7 @@ import TimelineActionAndStatus from "../../components/timeline-action-and-status
import IntersectionObserverProvider from "../../providers/intersection-observer";
import { TimelineLoader } from "../../classes/timeline-loader";
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
const NoteTimeline = React.memo(({ timeline }: { timeline: TimelineLoader }) => {
const notes = useSubject(timeline.timeline);
return (
<>
{notes.map((note) =>
note.kind === 6 ? (
<RepostNote key={note.id} event={note} maxHeight={1200} />
) : (
<Note key={note.id} event={note} maxHeight={1200} />
)
)}
</>
);
});
import GenericNoteTimeline from "../../components/generric-note-timeline";
const UserNotesTab = () => {
const { pubkey } = useOutletContext() as { pubkey: string };
@ -76,8 +61,7 @@ const UserNotesTab = () => {
<RelayIconStack ml="auto" relays={readRelays} direction="row-reverse" mr="4" maxRelays={4} />
</FormControl>
<NoteTimeline timeline={timeline} />
<GenericNoteTimeline timeline={timeline} />
<TimelineActionAndStatus timeline={timeline} />
</Flex>
</IntersectionObserverProvider>