Files
infinite-canvas/.agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md
T
HouYunFei fb79a15508 docs(vercel-react-best-practices): 添加 Vercel React 最佳实践规则文档
- 添加 sections 定义文件,包含性能优化各领域分类
- 添加规则模板文件,规范文档结构和标签定义
- 添加异步操作优化规则,包括防止瀑布流、并行化、延迟等待等
- 添加包大小优化规则,包括避免桶式导入、动态导入、预加载等
- 添加服务端性能优化规则,包括 API 路
2026-05-21 15:22:11 +08:00

1.8 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use useDeferredValue for Expensive Derived Renders MEDIUM keeps input responsive during heavy computation rerender, useDeferredValue, optimization, concurrent

Use useDeferredValue for Expensive Derived Renders

When user input triggers expensive computations or renders, use useDeferredValue to keep the input responsive. The deferred value lags behind, allowing React to prioritize the input update and render the expensive result when idle.

Incorrect (input feels laggy while filtering):

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} />
    </>
  )
}

Correct (input stays snappy, results render when ready):

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>
    </>
  )
}

When to use:

  • Filtering/searching large lists
  • Expensive visualizations (charts, graphs) reacting to input
  • Any derived state that causes noticeable render delays

Note: Wrap the expensive computation in useMemo with the deferred value as a dependency, otherwise it still runs on every render.

Reference: React useDeferredValue