Browsers are [not] quick; more on functional GUIs
UPDATE: This was complete rot. My test code was buggy, which caused the flicker. I patched it up and my draggable list moves smoothly now. Jeremy reports that he once tried an app that would re-create an entire (small) DOM tree on every keypress, and it worked reasonably fast. How do browsers manage to redraw pages as smoothly as they do?
An observation: web browsers move very fast when executing calls that modify the DOM.
For example, suppose list
is a list of items, of which x
is one, and you delete the item, then immediathttp://homepages.inf.ed.ac.uk/s0456219/ely insert it in the same place:
y = x.nextSibling;
list.removeChild(x);
list.insertBefore(y, x);
This will typically cause the whole list to be redrawn in the intermediate state, so the list gets shorter for a fraction of a second before the element is reinserted.
However, if you delete an element and reinsert it in a different place, the browser seems to redraw it smoothly, as if the element just moved:
y = x.previousSibling;
list.removeChild(x);
list.insertBefore(y, x);
That seems to be a difference of behavior, which I'm at a loss to explain.
In any event, this seems to rule out the "whole component replacement" that I talked about before, in implementing a purely-functional web GUI.
How to work around this difficulty? I still like the scoped, conditionalized structure that I outlined in that post. I suppose we could still have an inner function return a complete component, and have the runtime system compare it with the existing state of the component, executing a minimal series of DOM instructions to make the two agree.
Another approach, which I'm prefering, is to have the inner function return a "delta"—an expression representing how the component should change, something like a list of DOM instructions. I wouldn't want to allow the instructions in such an object to depend on one another, so I'd like to cook up a set of "deltas" which would be mutually independent, if possible. This would amount to a new mini-language for manipulating DOM trees, one that had no notion of sequential execution.