⚡ 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:
@@ -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 = () => {
|
||||
|
||||
Reference in New Issue
Block a user