Skip to content

⚡ Bolt: [performance improvement] Memoize resumeData to prevent redundant dependency triggers#432

Closed
aafre wants to merge 1 commit into
mainfrom
bolt-memoize-resume-data-7270264727104618021
Closed

⚡ Bolt: [performance improvement] Memoize resumeData to prevent redundant dependency triggers#432
aafre wants to merge 1 commit into
mainfrom
bolt-memoize-resume-data-7270264727104618021

Conversation

@aafre
Copy link
Copy Markdown
Owner

@aafre aafre commented Mar 29, 2026

💡 What: Wrapped the inline resumeData object passed to useCloudSave inside useSaveIntegration.ts with a useMemo hook, and cleaned up an exhaustive-deps eslint warning by extracting a complex expression into a separate variable.
🎯 Why: Passing an inline object literal ({ contact_info, sections, template_id }) to a custom hook that uses deep dependency tracking (like useCloudSave) causes the reference to change on every single render of the parent component. This forces useCloudSave's useEffect to fire continuously, which was executing an expensive JSON.stringify operation on the entire document payload, leading to main thread blocking and lag during typing or unrelated state updates.
📊 Impact: Eliminates redundant JSON.stringify evaluations inside useCloudSave. The auto-save change detection now only runs when the actual content (contact info, sections, template) or icon metadata legitimately changes, significantly improving responsiveness during typing in the editor.
🔬 Measurement: Verify by typing rapidly in any editor section (e.g., Summary or Experience). Profiling with React DevTools should show reduced time spent in the useEffect block of useCloudSave on every keystroke, and no unnecessary evaluations.


PR created automatically by Jules for task 7270264727104618021 started by @aafre

…undant cloud save dependency triggers

- Wrapped `resumeData` inline object literal in `useMemo` within `useSaveIntegration`.
- This prevents `resumeData` from getting a new reference on every render.
- Fixes an issue where `useCloudSave` was redundantly triggering expensive `JSON.stringify` checks on the deep dependency object during keystrokes or unrelated re-renders.
- Extracted `iconFilenames` to address an `eslint-disable-next-line` warning gracefully.
- Added `.jules/bolt.md` learning entry.

Co-authored-by: aafre <8656674+aafre@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes performance in the useSaveIntegration hook by memoizing resumeData and iconsForCloudSave to prevent reference inequality and redundant expensive operations in useCloudSave. It also adds a learning note to .jules/bolt.md regarding this optimization. The review feedback suggests refactoring the iconsForCloudSave memoization to remove an eslint-disable comment and avoid redundant calls to the registry by utilizing the derived iconFilenames string directly.

});
return iconsObj;
}, [iconRegistry.getRegisteredFilenames().join(',')]);
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This eslint-disable can be avoided. The useMemo callback calls iconRegistry.getRegisteredFilenames() again, which is redundant since iconFilenames is already derived from it and is in the dependency array. You can refactor the useMemo to work with iconFilenames directly. This will make the code more efficient and remove the need for the eslint-disable.

Suggested change
// eslint-disable-next-line react-hooks/exhaustive-deps
const iconsForCloudSave = useMemo(() => {
const iconsObj: { [filename: string]: File } = {};
if (!iconFilenames) {
return iconsObj;
}
const filenames = iconFilenames.split(',');
filenames.forEach((filename) => {
const file = iconRegistry.getIconFile(filename);
if (file) {
iconsObj[filename] = file;
}
});
return iconsObj;
}, [iconRegistry, iconFilenames]);
References
  1. The dependency array of useMemo should include the values that the memoized calculation depends on, not just the stable function references that produce those values. For arrays, a common pattern is to use array.join(',') as the dependency to detect changes in the array's content.

@aafre
Copy link
Copy Markdown
Owner Author

aafre commented Apr 11, 2026

Closing: superseded by #404 (better variable naming). Cherry-picked into #457.

@aafre aafre closed this Apr 11, 2026
@google-labs-jules
Copy link
Copy Markdown
Contributor

Closing: superseded by #404 (better variable naming). Cherry-picked into #457.

Understood. Acknowledging that this work is now obsolete and stopping work on this task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant