Files
90-RED-ComfyUI-LinkRouter/web/progressive.js
T
90-RED 8246479bee v1.2.0 — Adaptive drag modes, Heavy Deferred, large-workflow performance
Major features:
- Adaptive drag mode with 5 fixed modes (Normal, Freeze+Check, Freeze, Hide, Heavy Deferred)
- Heavy Deferred for lag-free dragging in large workflows (250+ nodes)
- Three drag phases: moving → held → released, with priority-based re-routing during pause
- Node hard-obstacle avoidance — links can never pass through nodes

Performance:
- Progressive routing with frame-budgeted progressive batches
- Fast graph signature for geometry-change detection
- OVG rebuild deferred during large drags
- Collision re-check limited to affected links only

Fixes:
- Hover no longer triggers full-workflow redraw
- Krea2 / Ultimate SD Upscale link disappearance during drag
- Stale sticky paths now validated before reuse
- Drag-endpoint dogleg for straight-line links

New modules: adaptive-policy, drag-policy, draw-policy, profiler, progressive, ui-policy
Tests: 39 automated tests covering routing, adaptive, drag, profiler
Floating bar: Adaptive 🧠 toggle, 5 fixed-mode buttons, debug row, Nodes 2.0 switch
2026-07-13 03:34:42 +08:00

45 lines
1.5 KiB
JavaScript

// Pure helpers for spreading expensive connector searches over multiple frames.
// Small/medium route sets are cheaper and look much better when they appear
// together. Progressive reveal is reserved for genuinely large updates.
export const PROGRESSIVE_ROUTE_THRESHOLD = 16;
export function shouldProgressivelyRoute(dragging, forceSync, jobCount) {
return !dragging && !forceSync && jobCount >= PROGRESSIVE_ROUTE_THRESHOLD;
}
export function progressiveItemLimit(total, percent) {
const pct = Math.max(1, Math.min(100, +percent || 10));
return Math.max(1, Math.ceil(total * pct / 100));
}
export function processRouteSlice(batch, routeOne, options = {}) {
const now = options.now || (() => performance.now());
const maxItems = options.maxItems ?? Infinity;
const budgetMs = options.budgetMs ?? Infinity;
const started = now();
let processed = 0;
while (batch.index < batch.jobs.length && processed < maxItems) {
const job = batch.jobs[batch.index++];
const result = routeOne(job);
if (result) batch.resultsById.set(job.entry.link.id, result);
processed++;
if (processed > 0 && now() - started >= budgetMs) break;
}
return {
processed,
done: batch.index >= batch.jobs.length,
remaining: batch.jobs.length - batch.index,
};
}
export function orderedRouteResults(entries, resultsById) {
const out = [];
for (const entry of entries) {
const result = resultsById.get(entry.link.id);
if (result) out.push(result);
}
return out;
}