防抖、缓存、性能优化——我给搜索框上了三道保险
⌨️ 开头:用户狂敲键盘,我的 API 费差点爆表
测试同学拿着手机,对着搜索框“duang duang duang”猛打:“巴黎、巴厘岛、巴拿马……”
我后台一看:3秒内发了15个请求!Google Suggest 接口差点把我拉黑。
更惨的是,页面卡成 PPT——每次输入都重新渲染建议列表,CPU 直接起飞。
我意识到:搜索框不是输入框,是性能雷区。
🛡️ 第一道保险:防抖(Debounce)——让请求“冷静一下”
我写了个自定义 Hook:
// hooks/useDebounce.js
import { useState, useEffect } from 'react';
export default function useDebounce(value, delay = 500) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
在搜索组件里:
const [keyword, setKeyword] = useState('');
const debouncedKeyword = useDebounce(keyword, 300);
useEffect(() => {
if (debouncedKeyword) {
fetchSuggestions(debouncedKeyword); // 只在用户停手后请求
}
}, [debouncedKeyword]);
✅ 用户打字时,请求被“憋住”;停手 300ms 后,才真正发出去。
✅ 省流量、省接口、省服务器,三赢!
🧠 第二道保险:useMemo ——别让 React 白干活
即使用了防抖,每次渲染建议列表时,React 还是会重新计算 JSX。
于是我用 useMemo 缓存渲染结果:
const suggestionList = useMemo(() => {
return suggestions.map(item => (
<div key={item.id}>{item.title}</div>
));
}, [suggestions]);
如果
suggestions没变,React 就直接复用上次的 DOM,不重算、不重绘。
💾 第三道保险:localStorage ——记住用户的“黑历史”
用户搜过“海岛”,下次打开 App 还想搜?别让他重打!
我在 useEffect 里加了缓存逻辑:
// 保存历史
useEffect(() => {
if (keyword.trim()) {
const history = JSON.parse(localStorage.getItem('searchHistory') || '[]');
const newHistory = [keyword, ...history.filter(h => h !== keyword)].slice(0, 10);
localStorage.setItem('searchHistory', JSON.stringify(newHistory));
}
}, [keyword]);
// 读取历史
const [history, setHistory] = useState([]);
useEffect(() => {
const saved = JSON.parse(localStorage.getItem('searchHistory') || '[]');
setHistory(saved);
}, []);
用户看到“历史记录”,感觉 App 很懂他——这就是用户体验的魔法。
🎯 结尾:搜索框不再“炸”,反而成了亮点
现在,我的搜索框:
- 打字不卡
- 请求不多
- 记忆力好
面试官问:“你怎么优化搜索性能?”
我微微一笑:“防抖 + useMemo + localStorage,三件套,稳如老狗。”
下一站,我要挑战最难的部分——让 AI 聊天机器人听懂人话!从 DeepSeek 到 Kimi,我是如何封装一个“万能聊天接口”的?