From 93911b5346948c5f2913fbfc5ee5b871f0a92653 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 20:19:14 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20icon=20export=20?= =?UTF-8?q?with=20concurrent=20processing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: aafre <8656674+aafre@users.noreply.github.com> --- .jules/bolt.md | 3 ++ .../src/hooks/useIconRegistry.ts | 33 ++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 00000000..02ff6032 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2026-05-05 - Parallelize independent async file operations +**Learning:** Sequential `await` in loops over independent asynchronous file operations (like `FileReader` conversions in `useIconRegistry`) creates significant unnecessary delays. JavaScript's single-threaded nature allows `Promise.all` to safely map distinct keys on a shared object concurrently without race conditions. +**Action:** Refactor sequential asynchronous tasks in loops into concurrent operations using `Promise.all`, while ensuring individual error handling remains intact. diff --git a/resume-builder-ui/src/hooks/useIconRegistry.ts b/resume-builder-ui/src/hooks/useIconRegistry.ts index 2f09a5ad..a1057c4f 100644 --- a/resume-builder-ui/src/hooks/useIconRegistry.ts +++ b/resume-builder-ui/src/hooks/useIconRegistry.ts @@ -169,22 +169,25 @@ export const useIconRegistry = (): UseIconRegistryReturn => { const targetFilenames = filenames || Object.keys(registry); const exportData: IconExportData = {}; - for (const filename of targetFilenames) { - 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); + // Use Promise.all to parallelize asynchronous file-to-base64 conversions + 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); + } } - } - } + }) + ); return exportData; }, [registry, fileToBase64]);