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
+15 -7
View File
@@ -779,18 +779,26 @@ export const Header: React.FC<HeaderProps> = ({
return () => { };
}
const observer = new ResizeObserver(() => {
updateHeaderHeight();
});
let rafId = 0;
const scheduleUpdate = () => {
if (rafId) return;
rafId = requestAnimationFrame(() => {
rafId = 0;
updateHeaderHeight();
});
};
const observer = new ResizeObserver(scheduleUpdate);
observer.observe(node);
window.addEventListener('resize', updateHeaderHeight);
window.addEventListener('orientationchange', updateHeaderHeight);
window.addEventListener('resize', scheduleUpdate);
window.addEventListener('orientationchange', scheduleUpdate);
return () => {
if (rafId) cancelAnimationFrame(rafId);
observer.disconnect();
window.removeEventListener('resize', updateHeaderHeight);
window.removeEventListener('orientationchange', updateHeaderHeight);
window.removeEventListener('resize', scheduleUpdate);
window.removeEventListener('orientationchange', scheduleUpdate);
};
}, [updateHeaderHeight]);