Timeline performance improvements (#12070)

* Use intersection observer for timeline segments

* only render when visible
This commit is contained in:
Josh Hawkins
2024-06-19 18:14:32 -05:00
committed by GitHub
parent e9cdef9f25
commit 5c33cdba4e
3 changed files with 88 additions and 47 deletions
@@ -1,9 +1,8 @@
import { useEffect, useCallback, useMemo, useRef, RefObject } from "react";
import { useCallback, useMemo, useRef, RefObject } from "react";
import MotionSegment from "./MotionSegment";
import { useTimelineUtils } from "@/hooks/use-timeline-utils";
import { MotionData, ReviewSegment, ReviewSeverity } from "@/types/review";
import ReviewTimeline from "./ReviewTimeline";
import { isDesktop } from "react-device-detect";
import { useMotionSegmentUtils } from "@/hooks/use-motion-segment-utils";
export type MotionReviewTimelineProps = {
@@ -165,42 +164,6 @@ export function MotionReviewTimeline({
],
);
const segmentsObserver = useRef<IntersectionObserver | null>(null);
useEffect(() => {
if (selectedTimelineRef.current && segments && isDesktop) {
segmentsObserver.current = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const segmentId = entry.target.getAttribute("data-segment-id");
const segmentElements =
internalTimelineRef.current?.querySelectorAll(
`[data-segment-id="${segmentId}"] .motion-segment`,
);
segmentElements?.forEach((segmentElement) => {
segmentElement.classList.remove("hidden");
segmentElement.classList.add("animate-in");
});
}
});
},
{ threshold: 0 },
);
// Get all segment divs and observe each one
const segmentDivs =
selectedTimelineRef.current.querySelectorAll(".segment.has-data");
segmentDivs.forEach((segmentDiv) => {
segmentsObserver.current?.observe(segmentDiv);
});
}
return () => {
segmentsObserver.current?.disconnect();
};
}, [selectedTimelineRef, segments]);
return (
<ReviewTimeline
timelineRef={selectedTimelineRef}