perf(app): reduce streaming rerenders and scroll churn (#67)
Amp-Thread-ID: https://ampcode.com/threads/T-019c793a-d087-762a-882a-8cc11e6101db Co-authored-by: Ubuntu <ubuntu@dev-yk.tail388b2e.ts.net>
This commit is contained in:
@@ -107,6 +107,8 @@ export function AgentStreamView({
|
||||
const hasScrolledInitially = useRef(false);
|
||||
const hasAutoScrolledOnce = useRef(false);
|
||||
const isNearBottomRef = useRef(true);
|
||||
const pendingAutoScrollFrameRef = useRef<number | null>(null);
|
||||
const pendingAutoScrollAnimatedRef = useRef(false);
|
||||
const streamItemCountRef = useRef(0);
|
||||
const streamScrollbarMetrics = useWebDesktopScrollbarMetrics();
|
||||
const [expandedInlineToolCallIds, setExpandedInlineToolCallIds] = useState<Set<string>>(new Set());
|
||||
@@ -214,6 +216,35 @@ export function AgentStreamView({
|
||||
[]
|
||||
);
|
||||
|
||||
const scheduleAutoScroll = useCallback(
|
||||
({ animated }: { animated: boolean }) => {
|
||||
pendingAutoScrollAnimatedRef.current =
|
||||
pendingAutoScrollAnimatedRef.current || animated;
|
||||
|
||||
if (pendingAutoScrollFrameRef.current !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
pendingAutoScrollFrameRef.current = requestAnimationFrame(() => {
|
||||
pendingAutoScrollFrameRef.current = null;
|
||||
const shouldAnimate = pendingAutoScrollAnimatedRef.current;
|
||||
pendingAutoScrollAnimatedRef.current = false;
|
||||
scrollToBottomInternal({ animated: shouldAnimate });
|
||||
});
|
||||
},
|
||||
[scrollToBottomInternal]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (pendingAutoScrollFrameRef.current !== null) {
|
||||
cancelAnimationFrame(pendingAutoScrollFrameRef.current);
|
||||
pendingAutoScrollFrameRef.current = null;
|
||||
}
|
||||
pendingAutoScrollAnimatedRef.current = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (streamItems.length === 0) {
|
||||
return;
|
||||
@@ -233,9 +264,9 @@ export function AgentStreamView({
|
||||
}
|
||||
|
||||
const shouldAnimate = hasScrolledInitially.current;
|
||||
scrollToBottomInternal({ animated: shouldAnimate });
|
||||
scheduleAutoScroll({ animated: shouldAnimate });
|
||||
hasScrolledInitially.current = true;
|
||||
}, [streamItems, scrollToBottomInternal]);
|
||||
}, [streamItems, scheduleAutoScroll]);
|
||||
|
||||
function scrollToBottom() {
|
||||
scrollToBottomInternal({ animated: true });
|
||||
|
||||
Reference in New Issue
Block a user