Skip to content

Conversation

@AustinMroz
Copy link
Collaborator

@AustinMroz AustinMroz commented Nov 1, 2025

If an Object URL is not revoked after being created, it causes a memory leak. Data URLs don't have this issue, but they can clutter the DOM, require more memory due to the base64 encoding, and may result in duplicate copies being kept in memory.

This is a WIP testing branch to determine

  • If this overhead is significant
  • If this affects the reports of memory leaks in the frontend

┆Issue is synchronized with this Notion page by Unito

@github-actions
Copy link

github-actions bot commented Nov 1, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 11/01/2025, 11:48:21 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Nov 1, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 11/02/2025, 12:01:22 AM UTC

📈 Summary

  • Total Tests: 497
  • Passed: 462 ✅
  • Failed: 0
  • Flaky: 5 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 453 / ❌ 0 / ⚠️ 5 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Nov 1, 2025

Bundle Size Report

Summary

  • Raw size: 12.2 MB baseline 12.2 MB — 🔴 +41 B
  • Gzip: 2.48 MB baseline 2.48 MB — 🔴 +51 B
  • Brotli: 1.95 MB baseline 1.95 MB — 🔴 +86 B
  • Bundles: 58 current • 58 baseline • 13 added / 13 removed

Category Glance
App Entry Points 🔴 +41 B (3.27 MB) · Vendor & Third-Party ⚪ 0 B (5.32 MB) · Other ⚪ 0 B (2.55 MB) · Graph Workspace ⚪ 0 B (724 kB) · Panels & Settings ⚪ 0 B (295 kB) · UI Components ⚪ 0 B (12.3 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.27 MB (baseline 3.27 MB) • 🔴 +41 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-mwvDCvOq.js (new) 2.89 MB 🔴 +2.89 MB 🔴 +596 kB 🔴 +450 kB
assets/index-DjsY15ay.js (removed) 2.89 MB 🟢 -2.89 MB 🟢 -596 kB 🟢 -450 kB
assets/index-Cnpmg0aN.js (new) 381 kB 🔴 +381 kB 🔴 +76.6 kB 🔴 +62.1 kB
assets/index-D2oE-dhT.js (removed) 381 kB 🟢 -381 kB 🟢 -76.6 kB 🟢 -62.1 kB
assets/index-BYpMh9oL.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -576 B 🟢 -482 B
assets/index-DaXAbMXE.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +577 B 🔴 +486 B

Status: 3 added / 3 removed

Graph Workspace — 724 kB (baseline 724 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-BgbDEC3n.js (removed) 724 kB 🟢 -724 kB 🟢 -141 kB 🟢 -109 kB
assets/GraphView-DdY7sO2z.js (new) 724 kB 🔴 +724 kB 🔴 +141 kB 🔴 +109 kB

Status: 1 added / 1 removed

Views & Navigation — 8.18 kB (baseline 8.18 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-Bm40ioAz.js (removed) 8.18 kB 🟢 -8.18 kB 🟢 -2.48 kB 🟢 -2.17 kB
assets/UserSelectView-D_j6miK5.js (new) 8.18 kB 🔴 +8.18 kB 🔴 +2.48 kB 🔴 +2.17 kB

Status: 1 added / 1 removed

Panels & Settings — 295 kB (baseline 295 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CreditsPanel-DxRxYb_X.js (new) 22.9 kB 🔴 +22.9 kB 🔴 +5.46 kB 🔴 +4.76 kB
assets/CreditsPanel-gUzOZjDu.js (removed) 22.9 kB 🟢 -22.9 kB 🟢 -5.45 kB 🟢 -4.76 kB
assets/KeybindingPanel--Mter3W4.js (new) 15.3 kB 🔴 +15.3 kB 🔴 +3.78 kB 🔴 +3.33 kB
assets/KeybindingPanel-B7oSAHU9.js (removed) 15.3 kB 🟢 -15.3 kB 🟢 -3.78 kB 🟢 -3.33 kB
assets/ExtensionPanel-Bm98bDuX.js (new) 12.1 kB 🔴 +12.1 kB 🔴 +2.84 kB 🔴 +2.49 kB
assets/ExtensionPanel-Dow6Zp_j.js (removed) 12.1 kB 🟢 -12.1 kB 🟢 -2.84 kB 🟢 -2.49 kB
assets/AboutPanel-BaVjPofd.js (removed) 10.3 kB 🟢 -10.3 kB 🟢 -2.68 kB 🟢 -2.34 kB
assets/AboutPanel-Cue8X4l7.js (new) 10.3 kB 🔴 +10.3 kB 🔴 +2.68 kB 🔴 +2.34 kB
assets/ServerConfigPanel-BnLEoQOq.js (removed) 8.23 kB 🟢 -8.23 kB 🟢 -2.18 kB 🟢 -1.92 kB
assets/ServerConfigPanel-CRVMmwyW.js (new) 8.23 kB 🔴 +8.23 kB 🔴 +2.18 kB 🔴 +1.92 kB
assets/UserPanel-Cm9HHY5T.js (new) 7.94 kB 🔴 +7.94 kB 🔴 +2.08 kB 🔴 +1.81 kB
assets/UserPanel-jgimyewo.js (removed) 7.94 kB 🟢 -7.94 kB 🟢 -2.07 kB 🟢 -1.81 kB
assets/settings-B-df0dZe.js 20.7 kB 20.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CI6OKvJn.js 22.9 kB 22.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CXGVj_nD.js 24.5 kB 24.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DfQ6dSJj.js 31.6 kB 31.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DJ2QgDzm.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRNLPMG6.js 23.7 kB 23.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DVVycxDc.js 19.9 kB 19.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-G6Dybj1b.js 24.1 kB 24.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-M6_GZccG.js 26 kB 26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 12.3 kB (baseline 12.3 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-B0477x3i.js (removed) 11.2 kB 🟢 -11.2 kB 🟢 -2.78 kB 🟢 -2.45 kB
assets/ComfyQueueButton-BDSCo6xU.js (new) 11.2 kB 🔴 +11.2 kB 🔴 +2.78 kB 🔴 +2.45 kB
assets/UserAvatar.vue_vue_type_script_setup_true_lang-C9bSkTC5.js 1.12 kB 1.12 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Data & Services — 11.4 kB (baseline 11.4 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-CYBjQ6r5.js (removed) 8.61 kB 🟢 -8.61 kB 🟢 -2.08 kB 🟢 -1.78 kB
assets/keybindingService-Di7n4uSM.js (new) 8.61 kB 🔴 +8.61 kB 🔴 +2.08 kB 🔴 +1.78 kB
assets/serverConfigStore-DT2Lu933.js 2.79 kB 2.79 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 1 added / 1 removed

Utilities & Hooks — 1.07 kB (baseline 1.07 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 5.32 MB (baseline 5.32 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-TH7eWvUO.js 3.22 MB 3.22 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-PESgPnbc.js 517 B 517 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-JDoAqkQm.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-B1kYNUlJ.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-PgD4wNjE.js 92.4 kB 92.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 2.55 MB (baseline 2.55 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/commands-B2KZRBmX.js 15.1 kB 15.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Bw-ckyga.js 13.9 kB 13.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C_NmM85I.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CuozCW4W.js 14 kB 14 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DGfVUJCR.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-dOJNDogK.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiE551e.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Fw7mvqSy.js 13.1 kB 13.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-FXnO1W4Q.js 13.2 kB 13.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bgu6_Hvd.js 59.5 kB 59.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bv0L0qvp.js 93 kB 93 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C3Doz3n_.js 67.6 kB 67.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C7eBl607.js 70.7 kB 70.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CHiV9ds2.js 76.4 kB 76.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CIc79Nts.js 68.5 kB 68.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DK5LmuBm.js 58.8 kB 58.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-J1nit7cj.js 66.3 kB 66.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-W97XgvAQ.js 80.4 kB 80.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8Ef8lY1m.js 196 kB 196 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BdF8EiZl.js 200 kB 200 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bv9Y8Cvp.js 229 kB 229 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-cMdB_wHv.js 179 kB 179 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CvNWbbtX.js 194 kB 194 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CwDWxzVz.js 215 kB 215 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CyPAVHpA.js 191 kB 191 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D6QTD6bJ.js 181 kB 181 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DKn6VmRJ.js 192 kB 192 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Nov 2, 2025
if (props.task.displayStatus === TaskItemDisplayStatus.Running) {
if (progressPreviewBlobUrl.value) {
URL.revokeObjectURL(progressPreviewBlobUrl.value)
const reader = new FileReader()
Copy link

Choose a reason for hiding this comment

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

[quality] high Priority

Issue: FileReader usage creates potential performance issue
Context: FileReader.readAsDataURL is synchronous and blocks the main thread. For large blob files, this could cause UI stuttering during progress preview updates.
Suggestion: Consider using URL.createObjectURL for better performance and only switching to data URLs if memory usage becomes problematic. The original Object URL approach was more performant.

if (progressPreviewBlobUrl.value) {
URL.revokeObjectURL(progressPreviewBlobUrl.value)
const reader = new FileReader()
reader.onloadend = () => {
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Missing error handling for FileReader operations
Context: FileReader operations can fail (e.g., corrupted blob, out of memory), but there's no error handler defined. This could lead to silent failures where progress previews don't show.
Suggestion: Add reader.onerror handler to gracefully handle failures and provide fallback behavior or user feedback.

const blobUrl = URL.createObjectURL(blob)
// Preview cleanup is handled in progress_state event to support multiple concurrent previews
const { setNodePreviewsByExecutionId } = useNodeOutputStore()
const reader = new FileReader()
Copy link

Choose a reason for hiding this comment

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

[performance] high Priority

Issue: Same performance concern as TaskItem.vue - FileReader blocks main thread
Context: FileReader.readAsDataURL is synchronous and will block the UI thread when processing large blobs. This is especially problematic for preview updates which should be fast and non-blocking.
Suggestion: Consider keeping URL.createObjectURL for performance-critical preview operations, or implement the change incrementally with performance monitoring.

setNodePreviewsByExecutionId(nodeParents.slice(0, i).join(':'), [
blobUrl
])
reader.onloadend = () => {
Copy link

Choose a reason for hiding this comment

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

[quality] medium Priority

Issue: Missing error handling for FileReader operations
Context: Same as TaskItem.vue - no error handler defined for FileReader operations. Critical for preview functionality reliability.
Suggestion: Add reader.onerror handler to gracefully handle failures and provide fallback behavior.

URL.revokeObjectURL(url)
}

delete app.nodePreviewImages[nodeLocatorId]
Copy link

Choose a reason for hiding this comment

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

[architecture] high Priority

Issue: Removed URL cleanup logic without ensuring consistency
Context: The revokePreviewsByLocatorId function removed URL.revokeObjectURL cleanup, but this function may still receive Object URLs from other code paths that weren't converted to data URLs.
Suggestion: Add conditional cleanup logic that checks if URLs are Object URLs (start with 'blob:') before attempting to revoke, ensuring backward compatibility during the transition period.

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Comprehensive PR Review

This review is generated by Claude. It may not always be accurate, as with human reviewers. If you believe that any of the comments are invalid or incorrect, please state why for each. For others, please implement the changes in one way or another.

Review Summary

PR: Remove Object URL usage for image previews (#6524)
Impact: 15 additions, 17 deletions across 3 files

Issue Distribution

  • Critical: 0
  • High: 3
  • Medium: 2
  • Low: 0

Category Breakdown

  • Architecture: 1 issue
  • Performance: 1 issue
  • Code Quality: 3 issues

Key Findings

Performance Impact

The switch from Object URLs to Data URLs addresses memory leak concerns but introduces significant performance trade-offs:

  • FileReader.readAsDataURL is synchronous and blocks the main thread
  • Data URLs are larger in memory (base64 encoding overhead)
  • Performance impact will be most noticeable with large image previews

Code Quality Issues

  • Missing error handling for all FileReader operations
  • Inconsistent cleanup logic (URL.revokeObjectURL still called in TaskItem.vue)
  • Pattern deviation from VueUse composables without clear justification

Architecture Concerns

  • Removed URL cleanup logic without ensuring consistency across all code paths
  • Mixed concerns: memory leak fix bundled with unrelated handleFile method refactor

Positive Observations

  • Clear intention to address reported memory leak issues
  • Consistent application of FileReader pattern across affected files
  • Good isolation of changes to preview-related functionality

Recommendations

Immediate Actions (Before Merge)

  1. Add error handling for all FileReader operations
  2. Remove unnecessary URL.revokeObjectURL calls for data URLs
  3. Consider splitting the handleFile refactor into a separate PR

Performance Monitoring

  1. Implement performance benchmarks for preview loading
  2. Monitor memory usage patterns with the new approach
  3. Consider hybrid approach: Object URLs for small images, data URLs for large ones

Testing Requirements

  • Test with various image sizes to validate performance impact
  • Test error scenarios (corrupted blobs, OOM conditions)
  • Verify no memory leaks remain with the new approach

This is a comprehensive automated review focusing on the Object URL to Data URL conversion and its implications.

@github-actions github-actions bot removed the claude-review Add to trigger a PR code review from Claude Code label Nov 2, 2025
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.

3 participants