aafre/resume-builder

perf(editor): Extract memoized list item components to prevent callback recreation

Open

#204 创建于 2026年1月18日

在 GitHub 查看
 (0 评论) (0 反应) (0 负责人)TypeScript (15 fork)auto 404
enhancementgood first issueperformance

仓库指标

Star
 (6 star)
PR 合并指标
 (PR 指标待抓取)

描述

Summary

Extract list items into memoized sub-components with useCallback handlers to prevent unnecessary re-renders from inline callback creation.

Background

Identified in PR #196 review: https://github.com/aafre/resume-builder/pull/196#discussion_r2674280330

Inline callbacks in .map() loops create new function instances on every render, causing child components to re-render unnecessarily.

Affected Files

  • ExperienceSection.tsx - Lines 131, 187, 198, 210, 230, 259 (most critical - nested loops)
  • EducationSection.tsx - Lines 165, 185, 199, 210, 223, 234
  • GenericSection.tsx - Lines 130, 149, 155, 190, 209, 215, 250, 269, 275
  • IconListSection.tsx - Lines 144, 165, 181, 194, 205, 213
  • ContactInfoSection.tsx - Lines 152, 176, 206, 229

Approach

  1. Create memoized sub-components:

    • DescriptionItem for experience descriptions
    • ExperienceEntry for experience cards
    • EducationEntry for education cards
    • ListItem variants for GenericSection
    • CertificationItem for IconListSection
    • SocialLinkItem for ContactInfoSection
  2. Use React.memo() wrapper on sub-components

  3. Use useCallback for handlers inside sub-components

  4. Pass stable callbacks from parent (memoized with useCallback)

Example Pattern

// Before
{items.map((item, index) => (
  <RichTextInput onChange={(value) => handleUpdate(index, value)} />
))}

// After
const MemoizedItem = React.memo(({ index, onUpdate }) => {
  const handleChange = useCallback((value) => onUpdate(index, value), [index, onUpdate]);
  return <RichTextInput onChange={handleChange} />;
});

Priority

Medium - Performance optimization. Most impactful for resumes with many experience entries and description points.

贡献者指南