尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用 useDeferredValue 化解 React 重渲染卡顿:Vercel React 最佳实践深度解析

用 useDeferredValue 化解 React 重渲染卡顿:Vercel React 最佳实践深度解析 前端教程【免费下载链接】preguntas-entrevista-reactPreguntas típicas sobre React para entrevistas de trabajo ⚛️项目地址https://gitcode.com/gh_mirrors/pr/preguntas-entrevista-react点击查看免费下载useDeferredValue是 React 并发特性Concurrent Features中用来延迟读取某个值的 Hook专门解决用户输入必须即时响应但基于输入的重计算过滤、图表、列表却很昂贵这一矛盾。本文以 Vercel React 最佳实践规则库中的rerender-use-deferred-value规则为骨架源文件见 rerender-use-deferred-value.md结合该规则库的整体分类体系与仓库内配套的面试题内容讲解它的原理、正确用法、适用场景、常见误区以及与useMemo、useTransition、useCallback的配合方式帮助你在大型列表过滤、可视化看板等重渲染场景下保持输入框的流畅手感。规则来源与定位它属于哪一类优化rerender-use-deferred-value是 Vercel 维护的 React/Next.js 性能最佳实践规则库 中 Re-render Optimizationrerender-前缀分类下的一条规则官方标注的impact 等级为 MEDIUMimpactDescription 为keeps input responsive during heavy computation在重计算期间保持输入响应。整个规则库按影响程度划分为 8 个类别其中与本文相关的两条相邻规则分别是规则解决的问题手段rerender-use-deferred-value输入即时、结果可稍后延迟读取某个值rerender-transitions频繁非紧急更新不阻塞 UI将更新标记为 transition两条规则共同服务于同一目标在重计算期间保持 UI 响应但切入点不同——useDeferredValue作用于值startTransition作用于更新。理解这个分类有助于你在实际项目里把这条规则放进正确的优化工具箱。问题场景输入框为什么会变卡当用户输入触发昂贵的计算或渲染时React 默认会在一次渲染中同步完成更新输入值和重算过滤结果两件事。若过滤逻辑例如对海量列表做模糊匹配耗时较长主线程会被长时间占用输入框就会出现明显的卡顿laggy每个按键都要等结果算完才响应。规则的原始示例用反模式Incorrect与正模式Correct对比展示了这一点。反模式直接在渲染期同步过滤function Search({ items }: { items: Item[] }) { const [query, setQuery] useState() const filtered items.filter(item fuzzyMatch(item, query)) return ( input value{query} onChange{e setQuery(e.target.value)} / ResultsList results{filtered} / / ) }这里的filtered在每次渲染时都会全量执行items.filter(...)且filtered与query处于同一次渲染中。每敲一个字符React 都要先更新输入框、再同步跑完整个过滤与结果列表渲染中间没有任何让路的机会输入自然变卡。正模式用 useDeferredValue 把重计算放到后台function Search({ items }: { items: Item[] }) { const [query, setQuery] useState() const deferredQuery useDeferredValue(query) const filtered useMemo( () items.filter(item fuzzyMatch(item, deferredQuery)), [items, deferredQuery] ) const isStale query ! deferredQuery return ( input value{query} onChange{e setQuery(e.target.value)} / div style{{ opacity: isStale ? 0.7 : 1 }} ResultsList results{filtered} / /div / ) }改造后的行为是输入框立即响应input的value仍绑定在即时值query上按键不等待重计算结果稍后跟上deferredQuery会滞后于queryReact 优先完成输入更新的渲染等有空闲时再以低优先级渲染基于deferredQuery的结果用户可感知正在过滤通过isStale query ! deferredQuery检测结果是否落后于输入配合透明度等视觉反馈示例中把结果区opacity降为 0.7避免用户以为结果卡死了。useDeferredValue 的核心机制从语义上讲useDeferredValue(value)会返回一个延迟版本的值在并发渲染期间React 会优先渲染最新值即value本身而deferredQuery可以落后于最新的query——这正是它能让输入保持响应、结果在空闲时补齐的原因。要点如下它不是防抖debounce也不是节流throttleuseDeferredValue不引入固定等待时间而是依赖 React 的调度器决定何时以低优先级重新渲染延迟值是否延迟、延迟多久由 React 根据主线程忙闲动态决定。它本身不做计算延迟的只是值的读取。真正的重计算必须另行承载——这正是规则强调把昂贵计算包在useMemo里并以延迟值作为依赖的原因见下文误区部分。首次渲染不延迟初始渲染时deferredQuery query只有当输入继续变化、React 判断需要让出主线程时两者才会暂时不一致随后在后台重渲染中重新对齐。规则强调的关键约束必须配合 useMemo规则末尾有一条醒目的NoteWrap the expensive computation inuseMemowith the deferred value as a dependency, otherwise it still runs on every render.将昂贵计算包在useMemo中、以延迟值作为依赖否则它仍然会在每次渲染时执行。这一点极易被忽略。仅使用useDeferredValue(query)却不改计算方式过滤仍会在每次渲染时全量执行延迟值只是看起来有个值实际收益有限。正确的组合是useDeferredValue(query)产出滞后值deferredQueryuseMemo(() items.filter(...), [items, deferredQuery])让过滤只在items或deferredQuery变化时重算结果组件接收filtered或deferredQuery作为 props。这样既避免了过滤逻辑在每次渲染中重复执行又让过滤工作整体进入低优先级渲染双管齐下消除卡顿。适用场景什么时候该用这条规则规则原文给出的何时使用清单非常明确过滤/搜索大型列表Filtering/searching large lists如商品列表、用户列表、日志检索输入即过滤是useDeferredValue最典型的用法昂贵的可视化图表、图形随输入响应Expensive visualizations reacting to input例如拖动滑块调整图表数据密度、缩放时间轴等场景图表重绘昂贵但滑块必须跟手任何会造成明显渲染延迟的派生状态Any derived state that causes noticeable render delays只要派生计算明显拖慢渲染就值得考虑把值拆成即时与延迟两份。判断标准很直观用户输入的那一刻是否明显感觉到 UI 卡顿是且卡顿源于输入触发的重计算就可以套用本规则。正确选型useDeferredValue 与 useTransition 如何分工仓库规则库里有一条相邻规则 rerender-transitions.md两者常被对比startTransition/useTransition把某次状态更新标记为低优先级例如startTransition(() setScrollY(window.scrollY))适用于你主动控制更新发生时机的场景如滚动位置跟踪、频繁非紧急的状态写入useDeferredValue当无法把状态更新包进 transition例如数据来自 props、来自第三方 Hook或渲染本身由外部触发时用它对值做延迟读取把昂贵的渲染与即时的输入解耦。换言之能包更新就用startTransition包不了更新就用useDeferredValue延迟值两者也可叠加见下文组合示例。组合使用useMemo useCallback useTransition useDeferredValue仓库的面试题库中有两篇与该主题直接相关的内容para-que-sirve-el-hook-use-deferred-value.json讲useDeferredValue允许以低优先级渲染某个值和 como-se-complementan-use-memo-use-callback-use-transition-y-use-deferred-value-para-optimizar-el-rendimiento.json讲四者如何互补。后者给出的分工总结非常精炼useMemo记忆昂贵的派生值计算、过滤依赖不变则不重算useCallback记忆函数引用避免每次渲染重建、导致 memo 子组件无谓重渲染useTransition降低非紧急更新的优先级例如重算列表让 UI 保持响应useDeferredValue延迟读取某个具体值适合输入必须即时、结果可以稍后的场景。典型组合模式源自该面试题内容function SearchProducts({ products }) { const [query, setQuery] useState() const [isPending, startTransition] useTransition() const deferredQuery useDeferredValue(query) const filtered useMemo(() { const normalized deferredQuery.trim().toLowerCase() return products.filter(product product.name.toLowerCase().includes(normalized) ) }, [products, deferredQuery]) const handleChange useCallback(event { const value event.target.value startTransition(() setQuery(value)) }, []) return ( input value{query} onChange{handleChange} / {isPending pFiltrando.../p} ul {filtered.map(product ( li key{product.id}{product.name}/li ))} /ul / ) }这个示例展示了四者如何各司其职、互为补充useCallback稳定事件处理器startTransition让查询更新本身可中断useDeferredValue进一步把重计算的输入值延迟化useMemo兜住过滤计算只随依赖变化而重跑。整体效果是输入即敲即应、过滤在后台进行、有明确的 pending 反馈正好是该规则保持输入响应目标在真实搜索组件中的完整落地。常见误区与注意事项结合规则原文与仓库配套内容总结几条实操红线只用 useDeferredValue、不包 useMemo过滤仍在每次渲染全量执行收益大打折扣规则 Note 已明确警告。在结果组件中直接使用即时值应把deferredQuery或基于它的filtered传给结果组件否则延迟失效。不要滥用如果重计算很快、UI 并无卡顿引入useDeferredValue反而增加复杂度与一次新旧值不一致的额外渲染此时保持简单即可。依赖数组必须正确useMemo的依赖应包含items与deferredQuery漏掉任一依赖都会造成过期结果或重复计算。做用户可见的反馈规则示例中isStale配合透明度变化正是为了让结果落后于输入的状态可见避免用户误判为卡死。小结rerender-use-deferred-value是 Vercel React 最佳实践规则库中重渲染优化类的中等影响规则给出了一套清晰、可直接套用的模式输入绑定即时值重计算绑定延迟值昂贵计算用 useMemo 承载用新旧值对比给出视觉反馈。当你在 React 项目里遇到输入框变卡、但过滤/图表重算确实很贵的场景时这是首选解法若还需进一步降低更新优先级可配合startTransition使用四类记忆化与并发 APIuseMemo、useCallback、useTransition、useDeferredValue按各自职责组合即可在复杂数据驱动的界面上保持流畅的交互体验。赞分享前端教程【免费下载链接】preguntas-entrevista-reactPreguntas típicas sobre React para entrevistas de trabajo ⚛️项目地址https://gitcode.com/gh_mirrors/pr/preguntas-entrevista-react点击查看免费下载相关推荐将 GBrain 连接到 ChatGPTOAuth 2.1 PKCE 的 MCP 集成完整指南将 GBrain 连接到 ChatGPTOAuth 2.1 PKCE 的 MCP 集成完整指南 本篇技术指南讲解如何将 GBrain 的知识库通过 MCP人工智能RAGAgent 记忆MCP 服务知识管理ZCode 前端性能优化用 React useDeferredValue 化解昂贵派生渲染造成的输入卡顿ZCode 前端性能优化用 React useDeferredValue 化解昂贵派生渲染造成的输入卡顿 导读 在 ZCode 这类重度交互的编码 Agent7个实用技巧React Markdown渲染从入门到企业级实践指南7个实用技巧React Markdown渲染从入门到企业级实践指南 React Markdown是一个功能强大的React组件能够将Markdown字符串安前端UI组件上一篇如何快速上手Petdex5分钟启动你的首个CLI动画宠物下一篇快速掌握Google Ads API开发使用google-api-php-client进行广告管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表