perf: batch mobile keyboard viewport handlers with rAF and debounce (#660)

Reduce layout thrashing during virtual keyboard open/close on mobile by
batching resize and visualViewport event handlers to once per animation
frame. No visual or behavioral changes — desktop is unaffected.

- MainLayout: rAF-batch visualViewport resize/scroll and window resize
  listeners (was firing 10-20x per frame during keyboard animation)
- Header: rAF-batch ResizeObserver and resize/orientationchange callbacks
- ChatContainer: rAF-batch ResizeObserver and resize fallback callbacks
- useDeviceInfo: 150ms debounce on resize listener (device type does not
  change during keyboard transitions)
This commit is contained in:
Gyumin Lee
2026-03-15 23:18:59 +02:00
committed by GitHub
parent bcb0ccb6ca
commit edf0a197a8
4 changed files with 60 additions and 21 deletions
@@ -281,17 +281,28 @@ export const ChatContainer: React.FC = () => {
updateChatScrollHeight();
let rafId = 0;
const scheduleUpdate = () => {
if (rafId) return;
rafId = requestAnimationFrame(() => {
rafId = 0;
updateChatScrollHeight();
});
};
if (typeof ResizeObserver === 'undefined') {
window.addEventListener('resize', updateChatScrollHeight);
window.addEventListener('resize', scheduleUpdate);
return () => {
window.removeEventListener('resize', updateChatScrollHeight);
if (rafId) cancelAnimationFrame(rafId);
window.removeEventListener('resize', scheduleUpdate);
};
}
const resizeObserver = new ResizeObserver(updateChatScrollHeight);
const resizeObserver = new ResizeObserver(scheduleUpdate);
resizeObserver.observe(container);
return () => {
if (rafId) cancelAnimationFrame(rafId);
resizeObserver.disconnect();
};
}, [currentSessionId, isDesktopExpandedInput, scrollRef]);