Saturday
Oct202007
Strategy: Send XHR Request on Lost Focus Instead of For Every Character

Robert Stewart shared this useful Ajax related scalability strategy:
We avoided XMLHttpRequests for individual keystrokes, choosing to go back to the server only when a field lost focus. Google can afford all the servers to handle the load for that, but we didn't want to.
Do you have a scalability strategy to share? Then share it!.
We avoided XMLHttpRequests for individual keystrokes, choosing to go back to the server only when a field lost focus. Google can afford all the servers to handle the load for that, but we didn't want to.
Do you have a scalability strategy to share? Then share it!.
Reader Comments (3)
Good strategy in many cases: "We avoided XMLHttpRequests for individual keystrokes, choosing to go back to the server only when a field lost focus. Google can afford all the servers to handle the load for that, but we didn't want to." But, obviously, not all.
One of the biggest pitfalls of a web-based application is that data entry is painful. Without Ajax, it's hard to make data entry fast--at all. And if you try to replace a fat client (e.g., a Windows frontend that can do fast auto-complete and searches to decrease the time it takes for an insurance clerk to pull up information) with a simple web form, you'll have a revolt.
That said, sometimes you CAN get away with not giving a user features like this and get away with it. This is the old performance trick of taking away parts and pieces that the end-user doesn't notice.. and continuing to do that until they DO NOTICE, then you've removed everything you easily can. :)
--
Dustin Puryear
Author, "Best Practices for Managing Linux and UNIX Servers"
http://www.puryear-it.com/pubs/linux-unix-best-practices
Another use for XHRs in a single page web app is to incrementally, and obviously asynchronously, synchronize client and server session state without forcing a page refresh. Perhaps you could even think of it as replicating session state from the master (for the duration of the client session, at least, stuff in the DOM, values in Javascript variables, etc. on the client) to the slave (in memory, replicated session manager, files or databases on the server side). Or, you might just call this incremental save.
At the risk of comically overextending this analogy, you can take a statement-based or row-based approach. Analogously to statement-based replication, you can have the client send command objects/messages to the server that cause the same actions to be taken on a data model on the server. For example, increase the contrast of an image by x%, rather than sending a copy of the entire changed image. If you are already using the Command pattern on the client to support multiple levels of undo, this might be an easy extension.
Alternatively, you can achieve higher scalability in some cases by sending the results of actions taken on the client back to the server, especially if you are worried about the model on the server getting out of sync with the cached model on the client. Also, it can sometimes be difficult to express the same commands on the client and the server and be confident you will always get the same results (see http://dev.mysql.com/doc/refman/5.1/en/replication-sbr-rbr.html"> MySQL docs on statement versus row-based replication).
I'm curious as to what Google Docs and other online doc or spreadsheet editors do. When they auto save, do they send editing commands, diffs, or the full doc/spreadsheet? What would Wireshark say?
The packet sniff (with new lines added for readability) reveals:
revisionID=dmxspsm_0f9dqw8:3&contentIsDelta=true&replacedLength=0&replacedStart=29&trailingLength=6&
preceedingSnippet=Here%20is%20line%201.%3Cbr%3ELine%202%3Cbr%3E&
followingSnippet=%3Cbr%3E%0A%0A&docContents=line%203%3Cbr%3E&
delta=%3D29%09%2Bline%203%253Cbr%253E%09%3D6%09&
oldLength=35&finis=true&POST_TOKEN=ZaAn5RUBAAA.iPfx3I1GPtSMu1BrknEREz4JSd4cYQ1sPi7fueGNtzo.AH9km5WGu1UjqBGxx9eo0g
for an auto save after I entered a new line with the text:
line 3
The value of the preceedingSnippet parameter has the rest of my tiny document. When I edited a larger document (this post), the preceedingSnippet really was just a snippet.
Obviously, there are going to be other cases where one or both of these approaches will actually provide amazing inverse scaling power that craters your servers. And maybe the approach Writely took for Google Docs is plainly obvious for editing a document online. But, I think it is worth considering for other apps that may not have as obvious of a data model as a document or spreadsheet that needs to be kept in sync between the client and the server.
With apologies for my verbosity.
I'd written a method some time ago to handle expensive dom queries / ajax requests.
So I decided to pull it out and http://germanforblack.com/javascript-sleeping-keypress-delays-and-bashing-bad-articles" title="My return article" rel="response">bash someone about with it. I'm sure that Robert Stewart was simply providing your readers with something as a starting point for this kind of application development.