Files
2026-07-13 21:36:17 +08:00

1.9 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
缓存重复函数调用 MEDIUM 避免冗余计算 javascript, cache, memoization, performance

缓存重复函数调用

当同一个函数在渲染期间被反复调用且传入相同输入时,使用模块级 Map 来缓存函数结果。

不正确(冗余计算):

function ProjectList({ projects }: { projects: Project[] }) {
  return (
    <div>
      {projects.map(project => {
        // slugify() 被调用了 100 多次,传入相同的项目名称
        const slug = slugify(project.name)
        
        return <ProjectCard key={project.id} slug={slug} />
      })}
    </div>
  )
}

正确(缓存结果):

// 模块级缓存
const slugifyCache = new Map<string, string>()

function cachedSlugify(text: string): string {
  if (slugifyCache.has(text)) {
    return slugifyCache.get(text)!
  }
  const result = slugify(text)
  slugifyCache.set(text, result)
  return result
}

function ProjectList({ projects }: { projects: Project[] }) {
  return (
    <div>
      {projects.map(project => {
        // 每个唯一项目名称只计算一次
        const slug = cachedSlugify(project.name)
        
        return <ProjectCard key={project.id} slug={slug} />
      })}
    </div>
  )
}

适用于单值函数的更简模式:

let isLoggedInCache: boolean | null = null

function isLoggedIn(): boolean {
  if (isLoggedInCache !== null) {
    return isLoggedInCache
  }
  
  isLoggedInCache = document.cookie.includes('auth=')
  return isLoggedInCache
}

// 认证状态变化时清除缓存
function onAuthChange() {
  isLoggedInCache = null
}

使用 Map(而非 hook),使其在任何地方都能工作:工具函数、事件处理器,而不仅仅是 React 组件。

参考:How we made the Vercel Dashboard twice as fast