Skip to content

Commit d593905

Browse files
committed
refactor: Optimize IntersectionObserver in Summary component
- Create IntersectionObserver only once and reuse it for performance. - Add `isObservingRef` to prevent redundant observer operations. - Improve observer lifecycle management for infinite scrolling.
1 parent 2d6a4c0 commit d593905

1 file changed

Lines changed: 34 additions & 23 deletions

File tree

  • packages/view/src/components/VerticalClusterList/Summary

packages/view/src/components/VerticalClusterList/Summary/Summary.tsx

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,49 @@ const Summary = ({ onLoadMore, isLoadingMore, enabled, isLastPage }: SummaryProp
3333

3434
const sentinelRef = useRef<HTMLDivElement>(null);
3535
const observerRef = useRef<IntersectionObserver | null>(null);
36+
const isObservingRef = useRef(false);
3637

37-
// Infinite scroll: Load data when sentinel is detected
38-
const handleRowsRendered = ({ stopIndex }: { startIndex: number; stopIndex: number }) => {
39-
if (!isLastPage && stopIndex >= clusters.length && sentinelRef.current && enabled) {
38+
// Create IntersectionObserver once and reuse it
39+
useEffect(() => {
40+
observerRef.current = new IntersectionObserver(
41+
(entries) => {
42+
if (entries[0].isIntersecting && !isLoadingMore && enabled) {
43+
onLoadMore();
44+
}
45+
},
46+
{
47+
root: null,
48+
rootMargin: "100px",
49+
threshold: 0.1,
50+
}
51+
);
52+
53+
return () => {
4054
if (observerRef.current) {
4155
observerRef.current.disconnect();
56+
observerRef.current = null;
4257
}
58+
isObservingRef.current = false;
59+
};
60+
}, [enabled, isLoadingMore, onLoadMore]);
4361

44-
observerRef.current = new IntersectionObserver(
45-
(entries) => {
46-
if (entries[0].isIntersecting && !isLoadingMore && enabled) {
47-
onLoadMore();
48-
}
49-
},
50-
{
51-
root: null,
52-
rootMargin: "100px",
53-
threshold: 0.1,
54-
}
55-
);
56-
57-
observerRef.current.observe(sentinelRef.current);
62+
// Infinite scroll: Observe sentinel when it's rendered
63+
const handleRowsRendered = ({ stopIndex }: { startIndex: number; stopIndex: number }) => {
64+
if (!isLastPage && stopIndex >= clusters.length && sentinelRef.current && enabled && observerRef.current) {
65+
if (!isObservingRef.current) {
66+
observerRef.current.observe(sentinelRef.current);
67+
isObservingRef.current = true;
68+
}
5869
}
5970
};
6071

72+
// Unobserve when sentinel is no longer needed
6173
useEffect(() => {
62-
return () => {
63-
if (observerRef.current) {
64-
observerRef.current.disconnect();
65-
}
66-
};
67-
}, []);
74+
if (isLastPage && observerRef.current && isObservingRef.current) {
75+
observerRef.current.disconnect();
76+
isObservingRef.current = false;
77+
}
78+
}, [isLastPage]);
6879

6980
const onClickClusterSummary = (clusterId: number) => () => {
7081
const selected = getClusterById(filteredData, clusterId);

0 commit comments

Comments
 (0)