hybrid web applications
DESCRIPTION
Can traditional document-based applications compete with the user experience frameworks such as Ember & Angular are known for?TRANSCRIPT
![Page 1: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/1.jpg)
Hybrid Web Applications with PJAX & HATEOAS
James Da Costa
@jamesdacosta [email protected]
jamesdacosta.com
![Page 2: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/2.jpg)
1885
2014
![Page 3: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/3.jpg)
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 old-school web and new technologies
![Page 4: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/4.jpg)
BackgroundNeeded 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
![Page 5: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/5.jpg)
Is there another way?
Retain server-side development environment
Fluid & engaging UX (like modern SPAs)
Not learn a big client-side framework
![Page 6: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/6.jpg)
Imagebase - Upload, tag, and edit images
![Page 7: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/7.jpg)
ToolsetDjango + Backbone.js
![Page 8: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/8.jpg)
BackboneModels
for managing data / syncing with server
!
Router wrapper around History API
![Page 9: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/9.jpg)
DemosThe Old School Application
PJAX & History API
Nesting Views & Modals
Discoverability (HATEOAS)
Animation
Push or Replace
Staying In Sync
![Page 10: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/10.jpg)
The Old School Application
Demo 1
![Page 11: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/11.jpg)
Basic PJAX & History API
![Page 12: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/12.jpg)
PJAXPushState + A JAX
![Page 13: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/13.jpg)
Normal vs PJAX
Browser makes normal request
Server responds with full HTML document
server
Browser
Normal Request
![Page 14: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/14.jpg)
Normal vs PJAX
Browser makes PJAX request and updates
location bar
Server responds with partial HTML
document
server
Browser
PJAX Request
![Page 16: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/16.jpg)
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')
![Page 17: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/17.jpg)
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
![Page 18: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/18.jpg)
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’)
![Page 19: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/19.jpg)
PJAX - Serverdef myView(request):
if request.headers[‘X-PJAX’]:
return renderPartial()
else:
return renderLayout()
![Page 20: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/20.jpg)
PJAX Benefits
Fewer requests
Fast response
Reduced load on server
Bookmarkable URL
Degrades nicely
![Page 21: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/21.jpg)
History APISession History and Navigation API
![Page 22: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/22.jpg)
Session History Browser Support
![Page 26: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/26.jpg)
Traditional + A JAXhttp://website.com/index.html
about
Unique resource has shared URL
![Page 28: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/28.jpg)
PushState + A JAXhttp://website.com/about.html
about
Unique resource has unique URL again
![Page 29: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/29.jpg)
PushState
var stateObj, title, url;
stateObj = {name: "fred"}
url = "/fred";
history.pushState(stateObj, title, url);
![Page 30: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/30.jpg)
PushState
www.bbc.co.uk
www.bbc.co.uk/fred {}
www.bbc.co.uk/news/
Update the UI e.g. via ajax
![Page 31: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/31.jpg)
PopState Event
window.onpopstate = function(e) {
console.log(e.state);
}
![Page 32: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/32.jpg)
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
![Page 33: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/33.jpg)
PopState
www.bbc.co.uk
www.bbc.co.uk/fred
www.bbc.co.uk/news/
{}
![Page 34: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/34.jpg)
DemoMaster - Detail with PJAX
![Page 35: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/35.jpg)
Visual Cues
![Page 36: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/36.jpg)
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
![Page 38: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/38.jpg)
$(document).on('pjax:send', function() {
$('#loading').show()
})
$(document).on('pjax:complete', function() {
$('#loading').hide()
})
![Page 39: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/39.jpg)
PJAXIn the wild
![Page 40: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/40.jpg)
PJAX - Who’s using it?
![Page 41: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/41.jpg)
https://blog.twitter.com/2012/improving-performance-on-twittercom
![Page 44: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/44.jpg)
Backbone.js
![Page 45: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/45.jpg)
Nesting Views & Modals
Demo 3
![Page 46: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/46.jpg)
Event Delegation & Element Lifetime
![Page 47: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/47.jpg)
Element Lifetime
Short lifetime (view)
Short lifetime (view)
Long lifetime (container)
![Page 48: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/48.jpg)
Event Delegation
Delegate events to elements with a long lifetime
Events fired on newly inserted HTML bubble up to container (delegate)
Fewer event handlers
![Page 49: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/49.jpg)
Event Delegation (jQuery)
$(container).on(‘click’, ‘a[data-pjax]’, function(){
do_something();
});
![Page 50: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/50.jpg)
HATEOASHypermedia As The Engine Of Application State
![Page 51: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/51.jpg)
![Page 52: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/52.jpg)
![Page 53: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/53.jpg)
Sport Link
![Page 54: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/54.jpg)
What if there were no linksAnd instead, the BBC published a document detailing
URL’s of all their pages
![Page 55: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/55.jpg)
+BBC WEBSITE
URLS !
VERSION 1.0
BBC WEBSITE URLS
!VERSION 2.0
BBC WEBSITE URLS
!VERSION 3.0
![Page 56: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/56.jpg)
Don’t cook URLs on the client, instead use the URLS
provided by the serverDecouples the client from the server
![Page 57: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/57.jpg)
Discoverability (HATEOAS)
Demo 4
![Page 58: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/58.jpg)
Animation & the Back Button
![Page 59: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/59.jpg)
AnimationFeedback 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
![Page 60: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/60.jpg)
Animation
Demo 5
![Page 61: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/61.jpg)
Animation
Spotify Web Player
Twitter App
![Page 62: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/62.jpg)
Back Button
![Page 63: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/63.jpg)
![Page 64: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/64.jpg)
http://www.xkcd.com/1309/
![Page 65: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/65.jpg)
![Page 66: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/66.jpg)
http://www.reddit.com/r/programming/comments/1uou3g/please_respect_the_back_button/
![Page 67: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/67.jpg)
![Page 68: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/68.jpg)
Epistemic Action
![Page 69: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/69.jpg)
Push or Replace
Demo 6
![Page 70: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/70.jpg)
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
![Page 71: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/71.jpg)
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
![Page 72: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/72.jpg)
Staying In Sync With The Server
![Page 73: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/73.jpg)
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
![Page 74: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/74.jpg)
Assign URLs to components
/image/58/panel/
/image/57/panel/
/image/56/panel/
![Page 75: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/75.jpg)
Staying In Sync With The Server
Demo 7
![Page 76: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/76.jpg)
Staying In Sync With The Server
Pros: Master and detail view stay in sync
Cons: making multiple requests for content
![Page 77: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/77.jpg)
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
![Page 78: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/78.jpg)
Staying In Sync With The Server
{
“content”: [
“div.thing”: “<p>content</p>”,
“div.related”: “<p>related content</p>”
]
}
![Page 79: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/79.jpg)
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
![Page 80: Hybrid Web Applications](https://reader034.vdocuments.site/reader034/viewer/2022052623/559950fe1a28abe26e8b478e/html5/thumbnails/80.jpg)
SummaryPJAX - 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