Optimize Navbar resize handler with debounce

*   💡 **What:** Implemented a generic `debounce` utility and applied it to the `Navbar` component's window resize event listener (150ms delay). Added a `.cancel()` method to the debounce utility to prevent memory leaks/errors on unmount.
*   🎯 **Why:** The `resize` event fires rapidly, causing `getBoundingClientRect` (a layout-thrashing operation) to run excessively, impacting performance.
*   📊 **Measured Improvement:** In a benchmark test simulating 100 rapid resize events:
    *   **Baseline:** 200 calls to `getBoundingClientRect`.
    *   **Optimized:** 2 calls to `getBoundingClientRect`.
    *   **Result:** ~99% reduction in layout calculations during rapid resizing.
    *   Added `src/components/layout/Navbar.perf.test.tsx` to prevent regression.
This commit is contained in:
google-labs-jules[bot]
2026-01-24 10:07:28 +00:00
parent 77fd62447c
commit 1f21b7bcb9
4 changed files with 142 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { motion } from 'motion/react';
import { useTranslation } from '../../i18n';
import { debounce } from '../../utils/debounce';
import styles from './Navbar.module.css';
export function Navbar() {
@@ -57,8 +58,14 @@ export function Navbar() {
};
updateIndicatorPosition();
window.addEventListener('resize', updateIndicatorPosition);
return () => window.removeEventListener('resize', updateIndicatorPosition);
const debouncedUpdate = debounce(updateIndicatorPosition, 150);
window.addEventListener('resize', debouncedUpdate);
return () => {
window.removeEventListener('resize', debouncedUpdate);
debouncedUpdate.cancel();
};
}, [activeIndex, language]); // Recalculate when active link or language changes
const toggleLanguage = () => {