Summary
Since updating to 1.51.0, Krita sits at a constant ~14% CPU while idle and has noticeable UI input lag (canvas pan/zoom, brush, trackpad pinch-zoom stutters/freezes) whenever the plugin is connected to a remote ComfyUI server. Disconnecting the server makes the lag disappear instantly; reconnecting brings it back. This did not happen on 1.50.0 with the exact same remote setup.
Setup
- Krita 5.x, macOS (Apple Silicon / M3)
- krita-ai-diffusion 1.51.0
- ComfyUI is remote: a RunPod pod reached through an HTTPS reverse proxy (
*.proxy.runpod.net) → higher latency and an occasionally-flaky websocket. A local/localhost ComfyUI does not seem affected.
- Full disclosure: I keep two tiny local patches in
network.py (force HTTP/1.1 for the proxy) and comfy_client.py (retry upload/download). eventloop.py is unmodified. I don't believe these cause the issue (it's clearly tied to the event loop being pumped on the GUI thread), but mentioning for transparency.
Profiling
sample <krita-pid> taken while idle and connected shows the time dominated by the asyncio↔Qt pump on the main/GUI thread:
- the 20 ms
QTimer in eventloop.py → process_python_events() → _loop.run_forever(),
- with deeply nested
QTimer::timerEvent → PyQt slot dispatch frames.
The active _handle_messages() websocket task (+ scheduler polling) appears to keep the loop producing ready callbacks on every tick, so the ~50 Hz main-thread pump does real work continuously and contends with GUI/input event delivery → the lag. When disconnected there is no async activity, the pump idles, and CPU/lag return to normal.
Likely cause / possible directions
The asyncio loop is pumped on the GUI thread every 20 ms via run_forever(). With a remote (higher-latency) ComfyUI the websocket/poll tasks keep it busy, so the main thread is starved. Possible directions:
- Skip/throttle the pump when there are no ready callbacks (avoid
run_forever() doing work every tick when idle), or make pumping event-driven instead of a fixed 20 ms timer.
- Run the asyncio loop on a dedicated thread (or adopt
qasync) so network I/O doesn't compete with the GUI thread.
- If 1.51 changed/added periodic polling (scheduler
poll_rate, connection keepalive, model refresh), consider widening the interval or making it event-driven.
Happy to share the full sample output or test any patch. Thanks for the excellent plugin! 🙏
Summary
Since updating to 1.51.0, Krita sits at a constant ~14% CPU while idle and has noticeable UI input lag (canvas pan/zoom, brush, trackpad pinch-zoom stutters/freezes) whenever the plugin is connected to a remote ComfyUI server. Disconnecting the server makes the lag disappear instantly; reconnecting brings it back. This did not happen on 1.50.0 with the exact same remote setup.
Setup
*.proxy.runpod.net) → higher latency and an occasionally-flaky websocket. A local/localhost ComfyUI does not seem affected.network.py(force HTTP/1.1 for the proxy) andcomfy_client.py(retry upload/download).eventloop.pyis unmodified. I don't believe these cause the issue (it's clearly tied to the event loop being pumped on the GUI thread), but mentioning for transparency.Profiling
sample <krita-pid>taken while idle and connected shows the time dominated by the asyncio↔Qt pump on the main/GUI thread:QTimerineventloop.py→process_python_events()→_loop.run_forever(),QTimer::timerEvent→ PyQt slot dispatch frames.The active
_handle_messages()websocket task (+ scheduler polling) appears to keep the loop producing ready callbacks on every tick, so the ~50 Hz main-thread pump does real work continuously and contends with GUI/input event delivery → the lag. When disconnected there is no async activity, the pump idles, and CPU/lag return to normal.Likely cause / possible directions
The asyncio loop is pumped on the GUI thread every 20 ms via
run_forever(). With a remote (higher-latency) ComfyUI the websocket/poll tasks keep it busy, so the main thread is starved. Possible directions:run_forever()doing work every tick when idle), or make pumping event-driven instead of a fixed 20 ms timer.qasync) so network I/O doesn't compete with the GUI thread.poll_rate, connection keepalive, model refresh), consider widening the interval or making it event-driven.Happy to share the full
sampleoutput or test any patch. Thanks for the excellent plugin! 🙏