Note: This post is from Keir Bowden (aka Bob Buzzard), a Force.com MVP, Salesforce Certified Technical Architect and CTO of BrightGen, a Platinum Cloud Alliance partner in the United Kingdom. He has been solving business problems with the Force.com platform since 2008 and building hybrid and HTML5 mobile applications since late 2010. He is a regular blogger on Apex, Visualforce and Salesforce1 solutions at The Bob Buzzard Blog.
Single-page versus Multi-page Applications
A Multi-Page Application (MPA) follows the traditional client-server architecture — as users navigate around the application, requests are sent to the Salesforce1 platform to retrieve the next Visualforce page, which is then returned to the browser. The following diagram shows the client/server interaction for a multi-page application that presents a list of accounts to a user who can then edit account details:
The request response flow is as follows:
- The user opens the application which retrieves the account list page.
- The user chooses an account to edit, which retrieves the account detail page and the view state containing the data for the page.
- The user updates the account detail, which posts the updated information and view state. This returns the account detail page and the updated view state.
- The user returns to step 1 to choose another account to edit.
While the page markup and resources are lightweight (as they only contain the information for the particular page) the application state is maintained in the Visualforce view state, which is sent back to the server with each request. As detailed in part 1 of this blog series, performant HTML5 web applications should try to reduce the number of round trips to the server, and should avoid using the Visualforce view state as this is a heavyweight resource for the device to manage. In a truly mobile environment, a multi-page application is likely to lead to slow response and request timeouts and for these reasons should be avoided.
The request response flow is as follows:
- The user opens the application which retrieves all pages for the application.
- The user chooses an account to edit.
- The user returns to step 4 to select another account to edit.
Single Page Applications are the approach I would always recommend for an application that is used in a truly mobile environment. Even if the user’s connection drops completely, unless this happens during the initial page or data request, or while data is being saved, the user will be able to continue working without interruption.
Logical pages are delivered to the JQuery Mobile framework in a single physical Visualforce page as a series of stacked <div> elements, each with a data-role attribute of “page”:
JQuery Mobile will hide all <div> elements aside from the first. Executing the example code above will display the element with the id of page1, while clicking the Page 2 button will hide the element with the id of page1 and display the element with the id of page2, as shown in the following screen shots:
The framework will also provide an animated transition, such as a fade or slide, when replacing one logical page with another.
Separating Presentation from Content
To activate Knockout, the applyBindings method must be executed, passing an instance of the View Model:
The Single Page Application example code from above can then be rewritten as:
When the page is rendered, the elements with the data-bind attribute of
"text: firstPage" or
The above example demonstrated a static binding, but one of the main benefits of Knockout identified above is that the user interface automatically updates when the view model changes. This is achieved through use of observables — properties that notify subscribers about changes.
The following view model defines an observable property named ‘product’, and a function that sets the value of ‘product’ to an element from a list of Salesforce products:
The product observable is then bound to an element on the page and a button provided to execute the setProduct method to update the observable value:
Like any other framework, Knockout will not be magically performant in all situations. When managing extremely simple data models, the additional overhead introduced by the framework outweighs the benefit of reduced DOM manipulation. As applications become larger and more complex, it becomes important to understand a little more about how the framework operates to understand the amount of work it is carrying out. Ryan Niemeyer has written a number of blog posts outlining performance issues encountered as applications scale and associated workarounds, as well as a tips for improving Knockout performance in general.
Knockout is at its heart a data-binding library — a building block of an HTML5 mobile application. It doesn’t provide functionality like routing and animations, but integrates well with other libraries that do. For this reason, Knockout is particularly suited to adding data-binding capabilities to existing applications. For development of a brand-new application, the effort required to identify and integrate a collection of libraries is not insignificant, in which case a full featured framework such as Angular may be more suitable.
An example HTML5 mobile survey application built as an SPA using JQuery Mobile and Knockout is available on github.
About the Author
Keir Bowden (aka Bob Buzzard), is a Force.com MVP, Salesforce Certified Technical Architect and CTO of BrightGen, a Platinum Cloud Alliance partner in the United Kingdom. He has been solving business problems with the Force.com platform since 2008 and building hybrid and HTML5 mobile applications since late 2010. He is a regular blogger on Apex, Visualforce and Salesforce1 solutions at The Bob Buzzard Blog.
This post was published in conjunction with the Technical Enablement team of the salesforce.com Customer-Centric Engineering group. The team’s mission is to help customers understand how to implement technically sound salesforce.com solutions. Check out all of the resources that this team maintains on the Architect Core Resources page of Salesforce Developers.