mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
perf: remove reply backlink subscription churn
Replaced per-reply useReplies subscriptions in backlink rendering with a precomputed directRepliesByParentCid map from thread-level filteredReplies. Also optimized quote link rendering in comment-content with scoped store subscription, reduced edit menu state churn, and improved DOM lookups with memoization to keep all backlink rendering data-local and eliminate repeated backend-state-driven reference churn during board scroll.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { Comment } from '@plebbit/plebbit-react-hooks';
|
||||
import { QUOTE_NUMBER_REGEX } from '../lib/utils/url-utils';
|
||||
import usePostNumberStore from '../stores/use-post-number-store';
|
||||
@@ -8,6 +8,30 @@ interface ReplyQuoteTargets {
|
||||
quotedPostNumbers: number[];
|
||||
}
|
||||
|
||||
const getReplyFingerprint = (reply: Comment) =>
|
||||
`${reply?.cid ?? ''}|${reply?.deleted ? '1' : '0'}|${reply?.removed ? '1' : '0'}|${reply?.edit?.timestamp ?? ''}|${reply?.state ?? ''}`;
|
||||
|
||||
const areQuotedByMapsEquivalent = (previousMap: Map<string, Comment[]>, nextMap: Map<string, Comment[]>) => {
|
||||
if (previousMap.size !== nextMap.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [quotedCid, nextReplies] of nextMap) {
|
||||
const previousReplies = previousMap.get(quotedCid);
|
||||
if (!previousReplies || previousReplies.length !== nextReplies.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < nextReplies.length; i++) {
|
||||
if (getReplyFingerprint(previousReplies[i]) !== getReplyFingerprint(nextReplies[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const extractReplyQuoteTargets = (replies: Comment[]) => {
|
||||
const quotedPostNumbers = new Set<number>();
|
||||
const replyQuoteTargets: ReplyQuoteTargets[] = [];
|
||||
@@ -38,6 +62,7 @@ const extractReplyQuoteTargets = (replies: Comment[]) => {
|
||||
};
|
||||
|
||||
const useQuotedByMap = (replies: Comment[] = []) => {
|
||||
const stableQuotedByMapRef = useRef<Map<string, Comment[]>>(new Map());
|
||||
const { replyQuoteTargets, quotedPostNumbers } = useMemo(() => extractReplyQuoteTargets(replies), [replies]);
|
||||
|
||||
// Subscribe only to post numbers referenced in this thread to avoid unrelated global store churn.
|
||||
@@ -92,6 +117,11 @@ const useQuotedByMap = (replies: Comment[] = []) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (areQuotedByMapsEquivalent(stableQuotedByMapRef.current, map)) {
|
||||
return stableQuotedByMapRef.current;
|
||||
}
|
||||
|
||||
stableQuotedByMapRef.current = map;
|
||||
return map;
|
||||
}, [replyQuoteTargets, quotedNumberToCid]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user