trying to understand sequence of events in a WebCanvas

HI Folks,

I recently converted a rather large display that I had been loading as external HTML to a webCanvas. It’s a motion sensor report from the WebInterface for the XTension home automation software for the Mac (all of which is written in Xojo by the way, most of it anyway, some of the low level device drivers are more traditionally built, http://MacHomeAutomation.com/) The control displays and updates fine, but I feel like i should be able to speed it up. The individual draws are fine, not too slow, but there can be lots of these on a page and then things really slow down. Am I right that there are several back and forth trips to the browser before I get anything drawn? When I call the invalidate the control is that a command to the browser which then generates the paint event with another round trip and then I send back my drawing instructions? I am playing with setting a webTimer with a short duration to keep the browser checking in with the server but so far that hasn’t seemed to make a difference. Or should I be calling refresh rather than invalidate? It also seems that each one loads individually with it’s own separate server connection. Most other things seem to group several into one transaction, but it seems that the paint events are all sent separately? Which really slows down loading a lot of them. Thats just my impression from watching my logs where I call the invalidate for them all in a loop and then I get the paint events one after another as they redraw. I expected to get all the paints, or most of them in a row and stack up all the outgoing data which would draw in the browser just as fast as it could. I know that would make it take longer to begin drawing. I just don’t understand these well enough yet to figure out how to make them work well. Whats the actual sequence of events for a WebCanvas?

Each webcanvas has its own script cache, and therefore its own server exchange, so yes each canvas communicates with the server on its own.

Also, keep in mind that each Paint event is “diffed” with the previous one. That is, the commands that you put in the Paint event are translated into JavaScript and then only the commands that have changed from one event to the next are sent to the browser. The advantage being that if all you do is change the color of something, while the script may be 100 lines long, only one is sent to the browser. It’s important to think about this when entering your drawing code because you could inadvertently cause the diff algorithm to take a lot of time.

[quote=209268:@Greg O’Lone]
Also, keep in mind that each Paint event is “diffed” with the previous one. That is, the commands that you put in the Paint event are translated into JavaScript and then only the commands that have changed from one event to the next are sent to the browser.[/quote]

Out of curiosity, how is this diffed?
A)
Does it look for the first change or does it diff across the entire set of instructions?
For example if I had:
A,B,C,D,E
and I did A,B,1,2,3,C,potato,D,E
Is it smart enough just to send “1,2,3 and potato” or does it send everything after the first change, “1,2,3,C,potato,D,E”

B)
Can it to advanced diff changes?
A,B,C,D,E
and I now do
C,D,E,A,B
Does it have to send all everything

C)
How does it handle images?
If the image is stored in memory the whole time and not modified does it not resend the image? What if the image changes it’s draw order but not the image? Example:
A,B,C,picture
TO:
A,picture,B,C

Can you combine elements into one canvas? Fewer canvases = better performance.

[quote=209276:@Brock Nash]Does it look for the first change or does it diff across the entire set of instructions?
For example if I had:
A,B,C,D,E
and I did A,B,1,2,3,C,potato,D,E
Is it smart enough just to send “1,2,3 and potato” or does it send everything after the first change, “1,2,3,C,potato,D,E”[/quote]
The engine looks at streams of lines on either side for common patterns.
In this case it will only send four instructions:
0. Insert 1 at position 3
0. Insert 2 at position 4
0. Insert 3 at position 5
0. insert potato at position 7

[quote=209276:@Brock Nash]B)
Can it to advanced diff changes?
A,B,C,D,E
and I now do
C,D,E,A,B
Does it have to send all everything[/quote]
In this case it’ll also send four:

  1. Insert C at position 1
  2. Insert D at position 2
  3. Insert E at position 3
  4. Remove everything after position 5

[quote=209276:@Brock Nash]C)
How does it handle images?
If the image is stored in memory the whole time and not modified does it not resend the image? What if the image changes it’s draw order but not the image? Example:
A,B,C,picture
TO:
A,picture,B,C[/quote]
Pictures are just like any other command. HTML5 Canvases require that the image already be in the browser’s cache to draw, so the only thing that’s actually changing is where the webcanvas’ draw command is:

  1. Insert picture at position 2
  2. Remove picture at position 5

The real trick is that the engine has no way to know how closely the new and the old match until it’s really too late. In the early experiments, the best results came from drawing all of the stuff that doesn’t change first (backgrounds, frames, etc) and then drawing the stuff that does change afterwards. This at least gives the engine a much smaller section of text to review.

It’s also important to keep in mind that a single line of code in Xojo often translates to more than one line of Javascript code in the background, so if your code is 10 lines in the Paint event, the entire script may be 20 in Javascript.

For those users who feel that the Diff engine is slowing them down, there’s a feature request to be able to disable it. feedback://showreport?report_id=32859

Thanks everybody. I’m thinking that maybe a web canvas isn’t the best solution to this particular problem, I may use this as an excuse to learn to write custom controls with the web api stuff. It’s just a bunch of divs that I change the color of for the most part.

It’s going out in the next release in this formI think, it really does work very well it’s just not as flashy and speedy and awesome as I would like. I’m thinking about some feature requests that I may make for the webCanvas in the future. Like the ability to preload the paint code. It would be terrific if I could open a window or embed a control and have the initial paint event already in that first exchange so that it didn’t have to startup empty and then make another call to the server and get the instructions. If I could do that I could make the interface FEEL instantaneous. Future updates can be a little laggy but since the interface is already there nobody would notice that. The initial load and all those back and forths with the server can be quite slow.