Ionosphere.tv
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf: debounce scroll→setState to 200ms — was causing 4900 React re-renders

The onScroll handler called setStartIndex on every scroll event,
triggering full React re-renders during scrolling. Now debounced
to only update section nav highlighting after scroll stops.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+9 -5
Trace-20260413T010910.json.gz

This is a binary file and will not be displayed.

+9 -5
apps/ionosphere/src/app/discussion/DiscussionContent.tsx
··· 354 354 return section; 355 355 }, [startIndex, flowItems]); 356 356 357 - // Track startIndex from scroll position for section nav highlighting 357 + // Track startIndex from scroll position for section nav highlighting (debounced to avoid re-renders during scroll) 358 358 const scrollContainerRef = useRef<HTMLDivElement>(null); 359 + const scrollDebounce = useRef<ReturnType<typeof setTimeout>>(); 359 360 useEffect(() => { 360 361 const el = scrollContainerRef.current; 361 362 if (!el || numCols <= 1) return; 362 363 const onScroll = () => { 363 - const colIdx = Math.round(el.scrollLeft / scrollColWidth); 364 - const itemIdx = allCols.slice(0, colIdx).reduce((sum, c) => c.endIndex, 0); 365 - setStartIndex(itemIdx); 364 + clearTimeout(scrollDebounce.current); 365 + scrollDebounce.current = setTimeout(() => { 366 + const colIdx = Math.round(el.scrollLeft / scrollColWidth); 367 + const itemIdx = allCols.slice(0, colIdx).reduce((sum, c) => c.endIndex, 0); 368 + setStartIndex(itemIdx); 369 + }, 200); 366 370 }; 367 371 el.addEventListener("scroll", onScroll, { passive: true }); 368 - return () => el.removeEventListener("scroll", onScroll); 372 + return () => { el.removeEventListener("scroll", onScroll); clearTimeout(scrollDebounce.current); }; 369 373 }, [numCols, scrollColWidth, allCols]); 370 374 371 375 // Wheel → horizontal scroll