fix(ui/text): stop idle 300ms re-render loop that could OOM the TUI (#8616)
Signed-off-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
+37
-16
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
import React, { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
||||||
import { Box, Text, render, useApp, useInput, useStdout } from "ink";
|
import { Box, Text, render, useApp, useInput, useStdout } from "ink";
|
||||||
import { MultilineInput } from "ink-multiline-input";
|
import { MultilineInput } from "ink-multiline-input";
|
||||||
import meow from "meow";
|
import meow from "meow";
|
||||||
@@ -574,13 +574,18 @@ function App({
|
|||||||
const queueRef = useRef<string[]>([]);
|
const queueRef = useRef<string[]>([]);
|
||||||
const isProcessingRef = useRef(false);
|
const isProcessingRef = useRef(false);
|
||||||
|
|
||||||
|
// Only run the animation tick when something is actually animating:
|
||||||
|
// the splash goose while the banner is up, or the spinner while loading.
|
||||||
|
// Otherwise we were re-rendering the entire viewport every 300ms forever,
|
||||||
|
// which rebuilds every turn's markdown and can OOM long-running sessions.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!bannerVisible && !loading) return;
|
||||||
const t = setInterval(() => {
|
const t = setInterval(() => {
|
||||||
setSpinIdx((i) => (i + 1) % SPINNER_FRAMES.length);
|
if (loading) setSpinIdx((i) => (i + 1) % SPINNER_FRAMES.length);
|
||||||
setGooseFrame((f) => f + 1);
|
if (bannerVisible) setGooseFrame((f) => (f + 1) % GOOSE_FRAMES.length);
|
||||||
}, 300);
|
}, 300);
|
||||||
return () => clearInterval(t);
|
return () => clearInterval(t);
|
||||||
}, []);
|
}, [bannerVisible, loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (turns.length > 0) setBannerVisible(false);
|
if (turns.length > 0) setBannerVisible(false);
|
||||||
@@ -1046,18 +1051,34 @@ function App({
|
|||||||
3,
|
3,
|
||||||
);
|
);
|
||||||
|
|
||||||
const contentLines = buildContentLines({
|
const contentLines = useMemo(
|
||||||
turn: currentTurn,
|
() =>
|
||||||
turnIndex: effectiveTurnIdx,
|
buildContentLines({
|
||||||
width: contentWidth,
|
turn: currentTurn,
|
||||||
loading: isLatest && loading,
|
turnIndex: effectiveTurnIdx,
|
||||||
status,
|
width: contentWidth,
|
||||||
spinIdx,
|
loading: isLatest && loading,
|
||||||
pendingPermission: isLatest ? pendingPermission : null,
|
status,
|
||||||
permissionIdx,
|
spinIdx,
|
||||||
toolCallsExpanded,
|
pendingPermission: isLatest ? pendingPermission : null,
|
||||||
queuedMessages: isLatest ? queuedMessages : [],
|
permissionIdx,
|
||||||
});
|
toolCallsExpanded,
|
||||||
|
queuedMessages: isLatest ? queuedMessages : [],
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
currentTurn,
|
||||||
|
effectiveTurnIdx,
|
||||||
|
contentWidth,
|
||||||
|
isLatest,
|
||||||
|
loading,
|
||||||
|
status,
|
||||||
|
spinIdx,
|
||||||
|
pendingPermission,
|
||||||
|
permissionIdx,
|
||||||
|
toolCallsExpanded,
|
||||||
|
queuedMessages,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
if (needsOnboarding && clientRef.current) {
|
if (needsOnboarding && clientRef.current) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user