[Twisted-Python] GUI responsiveness
jasper at peak.org
Wed Sep 14 14:26:19 EDT 2005
glyph at divmod.com wrote:
> On Wed, 14 Sep 2005 13:35:35 +0200, Antoine Pitrou
> <solipsis at pitrou.net> wrote:
>> Suppose a network event is taking some time to process (e.g. the
>> protocol is complex and there are some calculations involved), then your
>> GUI will become unresponsive (a 100ms delay is not critical for most
>> Internet protocols, but it is for GUIs).
> Not at all. A user clicks on a button; if they don't see an update
> for 100ms, that is barely enough time for them to flick their mouse
> over to another button. In fact, network latency is such that it is
> nearly impossible to provide faster than 100ms actual real response
> time even for highly performance-critical applications.
> If the UI isn't redrawing for 100ms, it is hard for the user to even
> notice, unless it is a continuous 100ms between redraws, in which case
> this GUI application is really doing quite a lot of work!
Normally you're a pretty sharp guy, but you're dead wrong about this.
Tenth of a second delays are very noticeable, quickly become quite
annoying, and make fine GUI control difficult as your mouse jumps
around, etc.. Keeping interupts shorter than 100ms is very much
critical for GUIs.
Your "Firefox is unresponsive" example is a special case, as usually
there is nothing to do while you wait for a page to load, so lack of
responsiveness goes unnoticed; even so, as soon as you try loading
multiple pages in background tabs it can become quite annoying, with
mouse clicks get lost, etc.
Now, I'm not a fan of threaded programming, and I definitely agree
wxPython doesn't integrate well with Twisted (IIRC it doesn't relinquish
control reliably), but Twisted is also lacking in this department. I
only see 2 ways to deal with moderate length processing chunks and still
allow a responsive GUI: split them off into a seperate thread/process
(yuck!), or painstakingly instrument every such piece of code to do it's
own time tracking and yield at an appropriate moment -- which isn't much
better than threading. Worse, I don't see a satisfactory way to deal
with the problem if it stems from some internal bit of Twisted taking
too big of a time slice. Manually split and recombine my network data
into smaller chunks? Run the whole GUI loop in a different thread?!
Unfortunately I don't have a solid idea of what Twisted could do better
here, as I'm only passingly familiar with it's internals. Perhaps some
way to get the Reactor to transmit network data in smaller chunks, with
more frequent pauses in between to allow for GUI responsiveness?
More information about the Twisted-Python