views:

389

answers:

3

I have a game on Google App Engine that's based on a 25x20 HTML table (the game board). Every 3 seconds the user can "move," which sends an AJAX request to the server, at which time the server rerenders the entire HTML table and sends it to the user.

This was easy to write, but it wastes a lot of bandwidth. Are there any libraries, client (preferably jquery) or server-side (must work with GAE), that help send differential instead of full updates for large tables? Usually only 5-10 tiles change on a given reload, so I feel like I could cut bandwidth use by an order of magnitude by sending just those tiles instead of all 500 every 3 seconds.

I'm also open to "you idiot, why are you using HTML tables"-type comments if you can suggest a better alternative. For example are there any CSS/DOM manipulation techniques I should be considering instead of using an HTML table? Should I use a table but give each td coordinates for an id (like "12x08") and then use jquery to replace cells by id?

A clarification: the tiles are text, not images.

+1  A: 

Without thinking of deltas:

You can use JSON quite easily to do this sort of thing. You can roll out your own compressed format, too.

I think compressing the data using gzip would help a lot. Most browsers nowadays support it, and it will greatly reduce the size of your responses.

strager
GAE gzips everything automatically if the browser supports it.
Brandon Thomson
+2  A: 

If you known the state between refreshes on the server side (see comment on question), you an send the data using JSON like so (not sure about exact syntax):

[
    { x: 3, y: 5, class: "asdf", content: "1234" },
    { x: 6, y: 5, class: "asdf", content: "8156" },
    { x: 2, y: 2, class: "qwer", content: "1337" }
]

Compact that (remove extra whitespace, etc.), gzip it, and send it to your Javascript. Surprisingly, the Javascript code to read this isn't that complicated (simply DOM manipulations).

strager
+2  A: 

You can model your game board as a multidimensional javascript array:

[[x0, x1, x2, x3 ... xn],
.....
.....]

each entry is an array representing a row. Each cell holds the numerical value of the game piece/square.

This model can be the "contract" you send to the server via ajax as JSON. The server calculates the same array and sends it back to the UI. You can render that array into a table, divs or whatever you like. Prototype.js and jQuery make creating dhtml super easy.

This array format will be much smaller than a whole HTML response laden with markup. It also gives you freedom to render the board in whatever way you like.

You can further compress this format and just send the deltas. For example: save the coordinates of tiles changed by the user and send those to the server:

[(x1, y2),.....(xn, yn)]

Or you can do it the other way around: send the full model array to the server, and have the server calculate the deltas.

Check out Sponty, and watch the ajax traffic every few minutes or so, we do something very similar: http://www.thesponty.com/ The client sends the full model to the server, and the server sends the diffs.

mahmoud
I like this idea, although I'll admit I can't figure out why it would be better to have the client send the whole model and the server send the diffs than for just the server to send the whole model.
Brandon Thomson
We make the server only send the diffs so that we can redraw only portions of the UI. This reduces redraw jitters and makes the update much faster.
mahmoud