Skip to content

⚡ Bolt: [performance improvement] Parallelize icon base64 conversions#444

Closed
aafre wants to merge 1 commit into
mainfrom
bolt-parallelize-icon-exports-11453954068509134295
Closed

⚡ Bolt: [performance improvement] Parallelize icon base64 conversions#444
aafre wants to merge 1 commit into
mainfrom
bolt-parallelize-icon-exports-11453954068509134295

Conversation

@aafre
Copy link
Copy Markdown
Owner

@aafre aafre commented Apr 4, 2026

💡 What: Refactored the exportIconsForYAML function in useIconRegistry.ts to map over filenames and use Promise.all instead of a sequential for...of await loop.
🎯 Why: Executing independent asynchronous file conversion tasks sequentially artificially limits throughput and blocks the main execution flow linearly.
📊 Impact: Total export time is now constrained by the longest single conversion rather than the sum of all conversions, significantly speeding up the save/export process for users with many custom icons.
🔬 Measurement: Verified by ensuring the linter passes for the refactored code and that existing tests still run successfully (accounting for pre-existing unrelated test failures).


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

Replaced a sequential `for...of` loop with `Promise.all` in `exportIconsForYAML` to concurrently process `FileReader` conversions, reducing I/O blocking time when exporting multiple resume icons.

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 parallelizes icon exports in the useIconRegistry hook by replacing a sequential for...of loop with Promise.all to improve performance. Feedback suggests refactoring the implementation to avoid side-effects within the map function by using Object.fromEntries and enhancing type safety through property preservation and the use of the unknown type.

Comment on lines +173 to +190
await Promise.all(
targetFilenames.map(async (filename) => {
const entry = registry[filename];
if (entry) {
try {
const base64Data = await fileToBase64(entry.file);
exportData[filename] = {
data: base64Data,
type: entry.file.type,
size: entry.file.size,
uploadedAt: entry.uploadedAt.toISOString(),
};
} catch (error) {
console.warn(`Failed to export icon ${filename}:`, error);
}
}
}
}
})
);
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

While the current implementation correctly parallelizes the asynchronous fileToBase64 operations, it relies on side-effects (mutating the exportData object) inside the map function. A more idiomatic approach is to return key-value pairs and use Object.fromEntries. Additionally, to align with repository standards, ensure all original properties are preserved during transformation to prevent data loss, and use unknown instead of any for better type safety.

    const exportResults = await Promise.all(
      targetFilenames.map(async (filename) => {
        const entry = registry[filename];
        if (!entry) return null;

        try {
          const base64Data = await fileToBase64(entry.file);
          return [
            filename,
            {
              ...entry,
              data: base64Data,
              type: entry.file.type,
              size: entry.file.size,
              uploadedAt: entry.uploadedAt.toISOString(),
            },
          ];
        } catch (error) {
          console.warn("Failed to export icon " + filename + ":", error);
          return null;
        }
      })
    );

    const exportData: IconExportData = Object.fromEntries(
      exportResults.filter((result): result is [string, unknown] => result !== null)
    );
References
  1. When transforming data objects, preserve all original properties by default to prevent accidental data loss, rather than hardcoding for an expected schema.
  2. When handling data from external sources, prefer using the unknown type over any to enforce type-checking and improve type safety.

@aafre
Copy link
Copy Markdown
Owner Author

aafre commented Apr 11, 2026

Closing: superseded by #421 (cleanest version). Cherry-picked into #457.

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

Closing: superseded by #421 (cleanest version). Cherry-picked into #457.

Understood. Acknowledging that this work is now obsolete as it has been superseded by #421 and cherry-picked into #457. 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