mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
debug: add temporary console.log statements for virtualization tracking
- Add [VIRTUALIZATION] prefixed logs to track viewport changes - Log scroll events, visible ranges, and performance metrics - Track auto-scroll decisions and user scroll detection - Monitor state cache hits/misses and evictions - Include timestamps and relevant data for debugging These logs help verify the virtualization behavior during testing.
This commit is contained in:
parent
227cd9c436
commit
55097ba8a3
4 changed files with 196 additions and 19 deletions
|
|
@ -545,10 +545,18 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
isStreaming,
|
||||
isHidden,
|
||||
onPerformanceIssue: (metric, value) => {
|
||||
console.warn(`ChatView performance issue: ${metric} = ${value}`)
|
||||
console.warn(`[VIRTUALIZATION] ChatView performance issue: ${metric} = ${value}`)
|
||||
},
|
||||
})
|
||||
|
||||
console.log("[VIRTUALIZATION] Virtualization hook initialized:", {
|
||||
messagesCount: modifiedMessages.length,
|
||||
isStreaming,
|
||||
isHidden,
|
||||
viewportConfig,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// Sync expanded rows with state manager
|
||||
useEffect(() => {
|
||||
if (stateManager) {
|
||||
|
|
@ -559,6 +567,12 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
}
|
||||
})
|
||||
setExpandedRows(newExpandedRows)
|
||||
|
||||
console.log("[VIRTUALIZATION] Synced expanded rows with state manager:", {
|
||||
expandedCount: Object.keys(newExpandedRows).length,
|
||||
visibleRange,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
}
|
||||
}, [modifiedMessages, stateManager, visibleRange])
|
||||
|
||||
|
|
@ -1404,9 +1418,16 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
// scrolling - use the optimized versions
|
||||
const scrollToBottomSmooth = useMemo(
|
||||
() =>
|
||||
debounce(() => optimizedScrollToBottom("smooth"), 10, {
|
||||
immediate: true,
|
||||
}),
|
||||
debounce(
|
||||
() => {
|
||||
console.log("[VIRTUALIZATION] Smooth scroll to bottom triggered")
|
||||
optimizedScrollToBottom("smooth")
|
||||
},
|
||||
10,
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
),
|
||||
[optimizedScrollToBottom],
|
||||
)
|
||||
|
||||
|
|
@ -1419,6 +1440,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
}, [scrollToBottomSmooth])
|
||||
|
||||
const scrollToBottomAuto = useCallback(() => {
|
||||
console.log("[VIRTUALIZATION] Auto scroll to bottom triggered")
|
||||
optimizedScrollToBottom("auto")
|
||||
}, [optimizedScrollToBottom])
|
||||
|
||||
|
|
@ -1580,6 +1602,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
|
||||
const itemContent = useCallback(
|
||||
(index: number, messageOrGroup: ClineMessage | ClineMessage[]) => {
|
||||
console.log("[VIRTUALIZATION] Rendering item at index:", {
|
||||
index,
|
||||
isGroup: Array.isArray(messageOrGroup),
|
||||
messageTs: Array.isArray(messageOrGroup) ? messageOrGroup[0]?.ts : messageOrGroup.ts,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// browser session group
|
||||
if (Array.isArray(messageOrGroup)) {
|
||||
return (
|
||||
|
|
@ -1959,12 +1988,21 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
itemContent={itemContent}
|
||||
onScroll={(e) => {
|
||||
const target = e.currentTarget as HTMLElement
|
||||
handleVirtuosoScroll(target.scrollTop)
|
||||
handleScrollStateChange({
|
||||
const scrollState = {
|
||||
scrollTop: target.scrollTop,
|
||||
scrollHeight: target.scrollHeight,
|
||||
viewportHeight: target.clientHeight,
|
||||
}
|
||||
|
||||
console.log("[VIRTUALIZATION] Virtuoso scroll event:", {
|
||||
...scrollState,
|
||||
distanceFromBottom:
|
||||
scrollState.scrollHeight - scrollState.scrollTop - scrollState.viewportHeight,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
handleVirtuosoScroll(target.scrollTop)
|
||||
handleScrollStateChange(scrollState)
|
||||
}}
|
||||
rangeChanged={handleRangeChange}
|
||||
atBottomStateChange={(atBottom) => {
|
||||
|
|
|
|||
|
|
@ -104,18 +104,29 @@ export function useOptimizedVirtualization({
|
|||
const devicePerf = detectDevicePerformance()
|
||||
const hasExpanded = stateManager.hasExpandedMessages()
|
||||
|
||||
console.log("[VIRTUALIZATION] Viewport config calculation:", {
|
||||
devicePerf,
|
||||
hasExpanded,
|
||||
isStreaming,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// Streaming takes priority
|
||||
if (isStreaming) {
|
||||
console.log("[VIRTUALIZATION] Using streaming viewport config:", config.viewport.streaming)
|
||||
return config.viewport.streaming
|
||||
}
|
||||
|
||||
// Expanded messages need more buffer
|
||||
if (hasExpanded) {
|
||||
console.log("[VIRTUALIZATION] Using expanded viewport config:", config.viewport.expanded)
|
||||
return config.viewport.expanded
|
||||
}
|
||||
|
||||
// Use device-specific config
|
||||
return getViewportConfigForDevice(devicePerf)
|
||||
const deviceConfig = getViewportConfigForDevice(devicePerf)
|
||||
console.log("[VIRTUALIZATION] Using device-specific viewport config:", deviceConfig)
|
||||
return deviceConfig
|
||||
}, [isStreaming, stateManager, config])
|
||||
|
||||
// Create optimized message groups
|
||||
|
|
@ -132,6 +143,14 @@ export function useOptimizedVirtualization({
|
|||
// Use stored scroll state
|
||||
const { scrollHeight, viewportHeight } = scrollState
|
||||
|
||||
console.log("[VIRTUALIZATION] Scroll event:", {
|
||||
scrollTop,
|
||||
scrollHeight,
|
||||
viewportHeight,
|
||||
distanceFromBottom: scrollHeight - scrollTop - viewportHeight,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
scrollManager.handleScroll(scrollTop, scrollHeight, viewportHeight)
|
||||
|
||||
// Update performance metrics
|
||||
|
|
@ -141,6 +160,12 @@ export function useOptimizedVirtualization({
|
|||
const atBottom = scrollManager.isAtBottom(scrollTop, scrollHeight, viewportHeight)
|
||||
setIsAtBottom(atBottom)
|
||||
setShowScrollToBottom(!atBottom && scrollManager.getState().isUserScrolling)
|
||||
|
||||
console.log("[VIRTUALIZATION] Scroll state updated:", {
|
||||
isAtBottom: atBottom,
|
||||
showScrollToBottom: !atBottom && scrollManager.getState().isUserScrolling,
|
||||
userScrolling: scrollManager.getState().isUserScrolling,
|
||||
})
|
||||
},
|
||||
[scrollState, scrollManager, performanceMonitor],
|
||||
)
|
||||
|
|
@ -148,29 +173,47 @@ export function useOptimizedVirtualization({
|
|||
// Handle visible range changes
|
||||
const handleRangeChange = useCallback(
|
||||
(range: { startIndex: number; endIndex: number }) => {
|
||||
console.log("[VIRTUALIZATION] Visible range changed:", {
|
||||
startIndex: range.startIndex,
|
||||
endIndex: range.endIndex,
|
||||
totalGroups: messageGroups.length,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
setVisibleRange(range)
|
||||
|
||||
// Update performance metrics
|
||||
const messageIndices = getVisibleMessageIndices(messageGroups, range)
|
||||
performanceMonitor.updateMessageCounts(
|
||||
messages.length,
|
||||
messageIndices.endIndex - messageIndices.startIndex + 1,
|
||||
)
|
||||
const visibleMessageCount = messageIndices.endIndex - messageIndices.startIndex + 1
|
||||
performanceMonitor.updateMessageCounts(messages.length, visibleMessageCount)
|
||||
|
||||
console.log("[VIRTUALIZATION] Performance metrics updated:", {
|
||||
totalMessages: messages.length,
|
||||
visibleMessages: visibleMessageCount,
|
||||
messageIndices,
|
||||
})
|
||||
|
||||
// Pin important messages in visible range
|
||||
const visibleGroups = messageGroups.slice(range.startIndex, range.endIndex + 1)
|
||||
let pinnedCount = 0
|
||||
visibleGroups.forEach((group) => {
|
||||
group.messages.forEach((msg) => {
|
||||
// Pin error messages and active tools
|
||||
if (msg.ask === "api_req_failed" || msg.say === "error" || (msg.ask === "tool" && !msg.partial)) {
|
||||
stateManager.pinMessage(msg.ts)
|
||||
pinnedCount++
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (pinnedCount > 0) {
|
||||
console.log("[VIRTUALIZATION] Pinned messages in visible range:", pinnedCount)
|
||||
}
|
||||
|
||||
// Cleanup old states periodically
|
||||
if (Math.random() < 0.1) {
|
||||
// 10% chance on each range change
|
||||
console.log("[VIRTUALIZATION] Running state cleanup")
|
||||
stateManager.cleanup()
|
||||
}
|
||||
},
|
||||
|
|
@ -218,11 +261,15 @@ export function useOptimizedVirtualization({
|
|||
performanceMonitor.updateDOMNodeCount()
|
||||
|
||||
// Log metrics in development
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
const report = performanceMonitor.getReport()
|
||||
if (report.issues.length > 0) {
|
||||
console.warn("Performance issues detected:", report.issues)
|
||||
}
|
||||
const report = performanceMonitor.getReport()
|
||||
console.log("[VIRTUALIZATION] Performance report:", {
|
||||
metrics: report.metrics,
|
||||
issues: report.issues,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
if (report.issues.length > 0) {
|
||||
console.warn("[VIRTUALIZATION] Performance issues detected:", report.issues)
|
||||
}
|
||||
}, 5000)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,16 +36,34 @@ export class AutoScrollManager {
|
|||
const isScrollingUp = deltaScroll < -5 // Small threshold to avoid noise
|
||||
const significantScroll = Math.abs(deltaScroll) > 10
|
||||
|
||||
console.log("[VIRTUALIZATION] AutoScrollManager.handleScroll:", {
|
||||
scrollTop,
|
||||
scrollHeight,
|
||||
clientHeight,
|
||||
deltaScroll,
|
||||
deltaTime,
|
||||
distanceFromBottom,
|
||||
scrollVelocity: this.scrollVelocity,
|
||||
isScrollingUp,
|
||||
significantScroll,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
if (isScrollingUp && distanceFromBottom > this.atBottomThreshold) {
|
||||
console.log("[VIRTUALIZATION] User scrolling detected: scrolling up")
|
||||
this.isUserScrolling = true
|
||||
this.isScrolling = true
|
||||
} else if (significantScroll && !this.isNearBottom(scrollTop, scrollHeight, clientHeight)) {
|
||||
console.log("[VIRTUALIZATION] User scrolling detected: significant scroll")
|
||||
this.isUserScrolling = true
|
||||
this.isScrolling = true
|
||||
}
|
||||
|
||||
// Reset user scrolling flag if they scroll to bottom
|
||||
if (distanceFromBottom <= this.atBottomThreshold) {
|
||||
if (this.isUserScrolling) {
|
||||
console.log("[VIRTUALIZATION] User scrolling reset: reached bottom")
|
||||
}
|
||||
this.isUserScrolling = false
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +79,7 @@ export class AutoScrollManager {
|
|||
|
||||
// Set timeout to detect end of scrolling
|
||||
this.scrollTimeout = setTimeout(() => {
|
||||
console.log("[VIRTUALIZATION] Scrolling ended")
|
||||
this.isScrolling = false
|
||||
this.scrollVelocity = 0
|
||||
this.scrollTimeout = null
|
||||
|
|
@ -75,7 +94,17 @@ export class AutoScrollManager {
|
|||
// 1. User is manually scrolling
|
||||
// 2. There are expanded messages (user might be reading)
|
||||
// 3. Currently in a scroll animation
|
||||
return !this.isUserScrolling && !hasExpandedMessages && !this.isScrolling
|
||||
const shouldScroll = !this.isUserScrolling && !hasExpandedMessages && !this.isScrolling
|
||||
|
||||
console.log("[VIRTUALIZATION] AutoScrollManager.shouldAutoScroll:", {
|
||||
shouldScroll,
|
||||
isUserScrolling: this.isUserScrolling,
|
||||
hasExpandedMessages,
|
||||
isScrolling: this.isScrolling,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
return shouldScroll
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,6 +127,7 @@ export class AutoScrollManager {
|
|||
* Reset user scrolling flag
|
||||
*/
|
||||
resetUserScrolling(): void {
|
||||
console.log("[VIRTUALIZATION] User scrolling reset manually")
|
||||
this.isUserScrolling = false
|
||||
}
|
||||
|
||||
|
|
@ -105,6 +135,7 @@ export class AutoScrollManager {
|
|||
* Force user scrolling state (e.g., when user expands a message)
|
||||
*/
|
||||
forceUserScrolling(): void {
|
||||
console.log("[VIRTUALIZATION] User scrolling forced")
|
||||
this.isUserScrolling = true
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +158,16 @@ export class AutoScrollManager {
|
|||
*/
|
||||
getScrollBehavior(currentTop: number, targetTop: number, maxSmoothDistance: number = 5000): ScrollBehavior {
|
||||
const distance = Math.abs(targetTop - currentTop)
|
||||
const behavior = distance > maxSmoothDistance ? "auto" : "smooth"
|
||||
|
||||
console.log("[VIRTUALIZATION] Scroll behavior calculated:", {
|
||||
currentTop,
|
||||
targetTop,
|
||||
distance,
|
||||
maxSmoothDistance,
|
||||
behavior,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// Use instant scroll for large jumps to avoid janky animation
|
||||
if (distance > maxSmoothDistance) {
|
||||
|
|
|
|||
|
|
@ -25,11 +25,17 @@ export class MessageStateManager {
|
|||
ttl: ttl,
|
||||
updateAgeOnGet: true,
|
||||
updateAgeOnHas: true,
|
||||
dispose: (value, _key) => {
|
||||
dispose: (value, key) => {
|
||||
// Update expanded count when items are evicted
|
||||
if (value.isExpanded) {
|
||||
this.expandedCount = Math.max(0, this.expandedCount - 1)
|
||||
}
|
||||
console.log("[VIRTUALIZATION] MessageStateManager state evicted:", {
|
||||
messageTs: key,
|
||||
wasExpanded: value.isExpanded,
|
||||
expandedCount: this.expandedCount,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
},
|
||||
})
|
||||
this.pinnedMessages = new Set<number>()
|
||||
|
|
@ -39,7 +45,20 @@ export class MessageStateManager {
|
|||
* Get the state of a message
|
||||
*/
|
||||
getState(messageTs: number): MessageState | undefined {
|
||||
return this.states.get(messageTs)
|
||||
const state = this.states.get(messageTs)
|
||||
if (state) {
|
||||
console.log("[VIRTUALIZATION] MessageStateManager cache hit:", {
|
||||
messageTs,
|
||||
state,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
} else {
|
||||
console.log("[VIRTUALIZATION] MessageStateManager cache miss:", {
|
||||
messageTs,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,6 +89,15 @@ export class MessageStateManager {
|
|||
this.expandedCount = Math.max(0, this.expandedCount - 1)
|
||||
}
|
||||
|
||||
console.log("[VIRTUALIZATION] MessageStateManager.setState:", {
|
||||
messageTs,
|
||||
previousState: existing,
|
||||
newState,
|
||||
expandedCount: this.expandedCount,
|
||||
cacheSize: this.states.size,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
this.states.set(messageTs, newState)
|
||||
}
|
||||
|
||||
|
|
@ -172,6 +200,9 @@ export class MessageStateManager {
|
|||
}
|
||||
})
|
||||
|
||||
const previousSize = this.states.size
|
||||
const previousExpandedCount = this.expandedCount
|
||||
|
||||
// Clear all states
|
||||
this.states.clear()
|
||||
this.expandedCount = 0
|
||||
|
|
@ -183,13 +214,33 @@ export class MessageStateManager {
|
|||
this.expandedCount++
|
||||
}
|
||||
})
|
||||
|
||||
console.log("[VIRTUALIZATION] MessageStateManager cleared:", {
|
||||
previousSize,
|
||||
previousExpandedCount,
|
||||
newSize: this.states.size,
|
||||
newExpandedCount: this.expandedCount,
|
||||
pinnedCount: this.pinnedMessages.size,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup old states (called automatically by LRU cache)
|
||||
*/
|
||||
cleanup(): void {
|
||||
const beforeSize = this.states.size
|
||||
this.states.purgeStale()
|
||||
const afterSize = this.states.size
|
||||
|
||||
if (beforeSize !== afterSize) {
|
||||
console.log("[VIRTUALIZATION] MessageStateManager cleanup:", {
|
||||
beforeSize,
|
||||
afterSize,
|
||||
removed: beforeSize - afterSize,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue