Ethanfel a8d8b3792c feat: add Quick (incremental) and Register refresh modes
- quick:    incremental rescan — re-walks only folders whose mtime changed
            (per-dir snapshot persisted to cache/scan_snapshot.json); reuses
            the cache for unchanged folders. Catches new/removed/renamed files.
- register: append specific file path(s) with NO folder walk (instant disk-wise)
- full:     unchanged default (clear cache -> full re-walk)

Frontend exposes all three as Extensions-menu commands; the graph node gains a
quick/full mode widget. POST /tenaciousload/refresh now takes {mode, folder, files}.
Unit-tested: incremental scan rescans only the changed dir; register adds/skips.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 01:25:12 +02:00

ComfyUI-Tenaciousload

ComfyUI-Tenaciousload

Self-contained fix for slow / black-screen ComfyUI loading when you have a huge model/LoRA collection (especially on a network mount). Just install the pack and restart ComfyUI — no nginx, no docker, no extra port.

The problem

ComfyUI's /api/object_info enumerates every node's inputs. With thousands of LoRAs (worse on a network mount) it becomes tens of MB and takes minutes to build on every page load — and the build freezes ComfyUI's whole event loop, so you get a long black screen, worst over a remote network.

How this pack fixes it

How it works: requests are served straight from an in-process cache; the slow build only runs on a miss or refresh

On load it injects an aiohttp middleware into ComfyUI that intercepts /object_info and /api/object_info and:

  • caches the built response in memory and on disk (./cache/), so it is built once instead of on every load — and the disk copy makes restarts instant (no rebuild);
  • serves it gzipped (≈85% smaller transfer, independent of any CLI flag), straight from cache without running the build;
  • because the build never runs on a normal load, the event-loop freeze (and the long black screen) is gone — page loads drop from minutes to seconds.

The only time a build runs is the first load after install, or when you explicitly refresh (below).

Refreshing after you add / remove models or LoRAs

The cache holds the old model lists until you refresh. Three modes are available from the Extensions menu (and the command palette):

Mode What it does Speed
Quick refresh Re-walks only the folders whose timestamp changed since the last scan; reuses the cache for the rest. Catches new / removed / renamed files. Fast on local disks; ~2× faster on a slow network mount (it still has to stat every folder to find which changed).
🔄 Full refresh Clears ComfyUI's folder cache and re-walks everything. Catches moves/deletes anywhere. Slowest (the original behaviour).
Register new file… You give it the path(s) of the file(s) you just added; it appends them to the cache with no folder walk. Instant disk-wise — only the object_info rebuild remains.

Also available:

  • Graph node 🔄 Refresh Models/LoRAs (Tenaciousload) with a mode widget (quick / full), for automated workflows.
  • HTTP: POST /tenaciousload/refresh with {"mode": "quick" | "full" | "register", "folder": "loras", "files": ["pack/new.safetensors"]}, then GET /object_info?nocache=1.

The first Quick refresh after install builds a folder index (one full walk), so it's as slow as a Full refresh that one time; every Quick refresh after that is incremental. The index is saved to ./cache/scan_snapshot.json.

Whichever mode you pick, the button shows a "refreshing…" toast and normal loads stay instant.

Requirements

None to install. Only ComfyUI itself (tested on 0.23.0) and Python ≥ 3.8. Everything used is Python stdlib or already bundled with ComfyUI (aiohttp, folder_paths, server). The web button needs no npm packages.

Install

Clone (or copy) this repo into your ComfyUI custom_nodes/ folder and restart ComfyUI:

cd ComfyUI/custom_nodes
git clone https://github.com/ethanfel/ComfyUI-Tenaciousload.git
# then restart ComfyUI

Nothing to pip install. ComfyUI-Manager can also install it from the registry.

Verify it's working

After restart, load the page once (first time builds + caches), then:

curl -s -H 'Accept-Encoding: gzip' -o /dev/null \
  -w '%{time_total}s | %{size_download} bytes | %header{x-tenaciousload-cache} | %header{content-encoding}\n' \
  http://127.0.0.1:8188/api/object_info   # use your ComfyUI port
# expect after the first load: ~0.00Xs | ~10 MB | HIT | gzip

ComfyUI's startup log should show Tenaciousload: object_info cache middleware installed.

This pack already gzips the cached object_info on its own. To also gzip everything else ComfyUI serves — most importantly the hundreds of frontend extension scripts, plus the other API responses — launch ComfyUI with its built-in compression flag:

python main.py --listen --port 8188 --enable-compress-response-body
  • It's a stock ComfyUI option (defined in comfy/cli_args.py), not part of this pack, and it's optional — Tenaciousload works fine without it.
  • It's strongly recommended for remote access: those extension scripts are many small requests that compress very well, so the flag noticeably cuts the total transfer on top of the object_info cache.
  • It costs a little CPU per response to compress; on a fast machine this is negligible compared to the bytes saved over the network.

Notes

  • The disk cache lives in ./cache/ (git-ignored). Delete it, or use the refresh button, to force a rebuild.
  • An nginx reverse proxy can cache object_info at the HTTP layer too, but this pack does it in-process so no extra service, container, or port is needed.

License

MIT — see LICENSE.

S
Description
No description provided
Readme MIT 466 KiB
Languages
Python 76%
JavaScript 24%