This document discusses techniques for building hybrid web applications using PJAX and HATEOAS. PJAX uses AJAX and the History API to update parts of pages for a fluid user experience while retaining server-side rendering. Event delegation and element lifetime are important concepts for managing views. HATEOAS decouples clients from servers by having servers provide link URLs rather than clients hardcoding them. Animation and respecting the back button are also discussed. Staying in sync between the client and server by giving components URLs and using server-sent events is covered.
3. Hybrid Web Applications
An approach to improving the user experience of
legacy web applications
Modernising applications in a way that doesn’t
ignore the fundamental tenets of the web
Borrowing ideas and techniques from the oldschool web and new technologies
4. Background
Needed to rewrite a server-side application and
wanted a better UX
Decided to learn about client side SPA
frameworks (Ember/Angular)
Realised there’s a steep learning curve
Big mindset shift from server-side to client-side
development
5. Is there another way?
Retain server-side development environment
Fluid & engaging UX (like modern SPAs)
Not learn a big client-side framework
16. PJAX Container
Identify where the partial HTML will be inserted
<div class="container" id="pjax-container">
Go to <a href=“/page/2" data-pjax>next page</a>.
</div>
$(document).pjax(a[data-pjax]', '#pjax-container')
17. PJAX Requests
Inform the server that you don’t want the full
page, just the partial
Could use a custom request header
If the browser doesn’t support the History API
fallback to normal request
18. PJAX Requests
If browser supports History API then intercept
links and make PJAX request
<a href=“/my-page/“ data-pjax>link</a>
and
XHR.setRequestHeader(‘X-PJAX’)
19. PJAX - Server
def myView(request):
if request.headers[‘X-PJAX’]:
return renderPartial()
else:
return renderLayout()
32. PopState Event
the popState event is fired when you go back
and forward in the browser history
the state object assigned to the url is returned
on a property of the event called state
this allows you to reconstruct the page without a
full reload
36. Visual Cues
Browsers have traditionally given visual cues
More power for developers (A JAX, History API)
Remember to keep the user in the loop
Slow down connection or put setTimeout in
jquery send
48. Event Delegation
Delegate events to elements with a long lifetime
Events fired on newly inserted HTML bubble up
to container (delegate)
Fewer event handlers
59. Animation
Feedback for the user is vital
Helps to suggest the behaviour of the back button
Helps to suggest available touch events
Native mobile/desktops rely on animation to help
the user feel in control of the application
UX is predictable
70. Push or Replace
history.pushState vs history.replaceState
Is this a new state or are we just altering the
existing state?
How are we presenting states? What will the
typical user want to do?
User Testing
71. ReplaceState
some potential use cases
Modal dialogues - users probably don't expect
the back button to undo the modal
Setting up the first page a user visits so we can
recreate state when they hit back
73. Staying In Sync
With The Server
PJAX makes updating a part of the page easy
What about other representations of the same
entity which already exist on the page?
Allow parts of the page to become stale or
occasionally refresh the page (jquery-idletimer)
Assign URL’s to components on the page
76. Staying In Sync
With The Server
Pros: Master and detail view stay in sync
Cons: making multiple requests for content
77. Staying In Sync
With The Server
How can we make a single request?
Server-Sent Events
Send HTML in JSON
Generic approach to updating content on the
client with JSON & HTML
78. Staying In Sync
With The Server
{
“content”: [
“div.thing”: “<p>content</p>”,
“div.related”: “<p>related content</p>”
]
}
79. Staying In Sync
With The Server
Sending HTML/JSON could work but lots of
benefits of using SSE:
Uses Traditional HTTP
Automatic reconnection
Send any type of event
80. Summary
PJAX - PushState+A JAX, URLs are important in modern JS heavy
apps
HATEOAS - decoupling client from server
Element Lifetime & Event Delegation - binding to long lived
element
Push or Replace - what should the back button do?
Animation - important for user feedback
Staying in Sync - giving components URLs