Asynchronous UI: the future of web interfaces

    While Ajax has become mainstream, user interfaces still cannot boast of instant responsiveness to user actions. The reason is that many developers are used to thinking in the term “request / response” and think that the UI should work in parallel with the front-end, waiting for a response from the server for each request. But why not update the interface before the answer arrives?

    The problem is quite acute, because performance is a critical feature of the UI. For example, Amazon estimates that page latency of just 0.1 seconds results in a 1% reduction in store turnover. According to Google, a delay of 0.5 seconds reduces the number of search queries by 20%.

    Ruby / JavaScript developer Alex MacCaw from Twitter offerslogical solution to the problem: extend the principles of Ajax not only to the front-end, but also to the user interface. He developed an appropriate framework for what is called AUI (Asynchronous User Interface).

    According to McCaw, the interface does not have to wait for the server to respond, because this leads to completely unnecessary delays. For example, what does the interface expect in this screenshot, why does it block user actions?



    After all, the letter can be quietly sent in the background, and the user does not have to wait for a message about the successful sending. Of course, except in those rare cases when you send really importantletter and want to know exactly what it went to the addressee. But in fact, this is an illusion of reliability, because the sender server cannot guarantee that the addressee will actually receive this letter.

    One way or another, the Gmail interface delayed example applies to hundreds and thousands of other web applications in which the user interface expects a response from the server before allowing any action to be taken.

    Alex McCaw has developed the Spine JavaScript framework . It implements a conceptually new approach in which the UI works independently of the server side of the application, that is, asynchronously.

    As a result, you can significantly increase the performance of the UI. Alex gives an example unpretentious web application, in which you can evaluate the speed of Spine (backend on Ruby). Note that all actions are instantaneous, while Ajax REST calls are sent in the background.

    To implement an asynchronous UI, you need to observe three basic principles:
    • Transferring state and rendering to the client side
    • Intelligent data preload
    • Asynchronous server communication
    On the first two points, Alex McCaw refers everyone to his Javascript Web Applications book , and on the third point he explains in more detail with the following example. Suppose a user wants to change the name of a page while working with CMS. When working in an asynchronous UI, he can do this instantly and continue working with the application without waiting for a response from the server. In Spine terminology, we are dealing with a model called Page. When changing the model name in the controller, the following occurs:

    page = Page.find(1)
    page.name = "Hello World"
    page.save()

    As soon as the call occurs save(), Spine performs the following actions:
    • Check callbacks and save changes to memory
    • Change event notifications and user interface updates
    • Sending an Ajax PUT request to the server with a change message
    Note that the Ajax request is sent to the server after updating the user interface.

    Since Alex McCaw has long been working with such technologies for a long time, he worked out various synchronizations with the server in order to avoid errors. For example, he implemented client-side data validation. Of course, this is not always possible (for example, checking for the uniqueness of an attribute requires access to the database). There is no easy solution, so the discussion continues. It is easier to deal with network errors: to avoid closing the browser before sending a request to the server, it is enough to monitor the occurrence of the event window.onbeforeunloadand notify the user if there is an unsent request.

    window.onbeforeunload = ->
      if Spine.Ajax.pending
        '''Data is still being sent to the server; 
           you may lose unsaved changes if you close the page.''' 

    Similarly, if the server returns an error, this can be passed on to the user. Such errors occur relatively rarely, so you should not particularly focus on them. It is enough to notify the user, record the event in the log and synchronize again.

    Requests to the server are sent in the background strictly in turn to avoid any errors (when a request to update data arrives earlier than a request to create a new element).

    Another technique that Alex McCaw offers following the Backbone example is the generation of temporary CIDs on the client side, which are a replacement for the unique IDs generated on the server side. This approach eliminates delays and maintains an instant response for any JavaScript functions that need to generate IDs.

    Backbone uses different APIs for different types of identifiers.

    Users.getByCid(internalID)
    Users.get(serverID)

    To get rid of this “duplicity”, Spine takes a slightly different approach. Here, temporary identifiers (pseudo GUIDs) are used until a response from a server with a real ID is received, and after that Spine switches to it, but both identifiers remain accessible through a single API.

    It is clear that in some cases the use of AUI is inappropriate. For example, in financial applications or Internet banking, the interface should accurately reflect the movement of financial resources, receiving a response from the server. But in most cases, AUI has clear advantages over traditional Ajax application interfaces.

    Also popular now: