Extensions/ComfyUI-Subgraph-Preview
ComfyUI Extension

ComfyUI-Subgraph-Preview

I got tired of waiting for ComfyUI to enable Subgraph previews so I made my own patch.

By marcsole96·Created 8 days ago·Updated 7 days ago· 1
marcsole96/ComfyUI-Subgraph-Preview
Nodes
On cloudLocal install
Stars1
Updated7 days ago
Readme

ComfyUI-Subgraph-Preview

<p align="center"> <img src="examples/banner.png" width="400" alt="Live preview is back"> </p>

Shows sampler previews on subgraph nodes, so you don't have to open the subgraph to see what's going on.

If you collapse part of your workflow into a subgraph, the preview disappears. The subgraph node just sits there while the sampler runs inside it and you can't see anything until it finishes. This extension draws the preview on the subgraph node itself, and it can also keep the final image there once the run is done.

It's frontend only. No new nodes, no Python dependencies, nothing on the backend.

What it looks like

The sampler is running inside the subgraph, and you can watch it from outside.

<p align="center"> <img src="examples/demo.gif" width="260" alt="Live sampler preview drawn on a subgraph node"> </p>

Why it doesn't work by default

The preview data is already there. ComfyUI sends every preview frame to all the parent execution ids, so app.nodePreviewImages[<host locator>] gets filled while a sampler inside the subgraph is running. Nothing ever draws it.

Two things get in the way:

  1. Drawing promoted previews was only implemented for the Vue Nodes renderer, so on the normal canvas you get nothing.
  2. showCanvasImagePreview() gives up on subgraph nodes, because SubgraphNode.widgets is a computed getter and can't hold a preview widget.

So this extension adds the drawing step that's missing on the canvas renderer.

Install

With ComfyUI Manager, search for "Subgraph Preview" and install it.

Or clone it into ComfyUI/custom_nodes/:

git clone https://github.com/marcsole96/ComfyUI-Subgraph-Preview

Then restart ComfyUI and refresh the browser. It loads frontend code, so a hard refresh helps.

Settings

They're under Settings > LiteGraph > Subgraph:

| Setting | Default | What it does | |---|---|---| | Show generation previews on subgraph nodes | on | Draws the live sampler preview on the subgraph node | | Keep the final image on subgraph nodes | on | After the run, keeps showing the output of the deepest interior node that made images | | Max preview height on subgraph nodes | 320 | How tall the preview can get (96 to 1024) |

If you resize a subgraph node by hand, the extension stops managing its height. It only touches a height it set itself.

Compatibility

Built and tested on ComfyUI 0.33.0 with comfyui-frontend-package 1.48.7, on the classic canvas renderer. In Vue Nodes mode it turns itself off, since that renderer already draws these previews.

It hooks into frontend internals rather than a public API, so a big frontend refactor could break it. If that happens, open an issue.

How it works

A few notes in case anyone wants to do something similar:

  • It hooks LGraphCanvas.drawNode instead of LGraphNode.onDrawBackground. Subgraph nodes define their own onDrawBackground, which shadows anything you put on LGraphNode.prototype, so that hook never runs. Every node passes through drawNode, and by then the context is already translated to the node origin, so you get the same coordinates onDrawBackground would have given.
  • To pick what to show, it first checks the node's own preview, then walks the interior nodes (up to 8 levels of nesting) for a live preview that the fan-out missed, and finally falls back to the output images of the deepest interior node that produced any.
  • The preview is anchored to the node's computed content height, not its current height. node.size gets saved into the workflow and already includes the preview block, so anchoring to that makes the node grow taller every time you save and reload.
  • Decoded images are cached per node and only rebuilt when the URLs change. Settings are cached for 250ms so the settings store isn't queried for every node on every frame.
  • Only the foreground canvas gets invalidated. If you dirty the background too, ComfyUI's own preview widget starts dropping frames, because it defers its drawImage into a microtask.

If something isn't working

Open the browser console and run __sgpDebug(). It says whether the hook is installed, and then for each subgraph node prints the locator id, whether there's a live preview, how many URLs it resolved, how many times it drew, how many images decoded, and the node size. After that it logs every preview frame that arrives, so you can queue a run and see what comes in.

License

MIT, see LICENSE.