Hybrid Web Applications
with PJAX & HATEOAS

James Da Costa
@jamesdacosta

james@bright-interactive.com
jamesdacosta.com
1885

2014
Hybrid Web Applications
An approach to improving the user experience of
legacy web applications
Modernising applications i...
Background
Needed to rewrite a server-side application and
wanted a better UX
Decided to learn about client side SPA
frame...
Is there another way?
Retain server-side development environment
Fluid & engaging UX (like modern SPAs)
Not learn a big cl...
Imagebase - Upload, tag, and edit images
Toolset
Django + Backbone.js
Backbone
Models
for managing data / syncing with server
!

Router
wrapper around History API
Demos
The Old School Application
PJAX & History API
Nesting Views & Modals
Discoverability (HATEOAS)
Animation
Push or Rep...
Demo 1

The Old School
Application
Basic PJAX &
History API
PJAX
PushState + A JAX
Normal vs PJAX
server

Browser makes normal
request
Server responds with
full HTML document

Normal
Request

Browser
Normal vs PJAX
Browser makes PJAX
request and updates
location bar
Server responds with
partial HTML
document

server

PJA...
jQuery-PJAX

https://github.com/defunkt/jquery-pjax
PJAX Container
Identify where the partial HTML will be inserted
<div class="container" id="pjax-container">	
	

Go to <a h...
PJAX Requests
Inform the server that you don’t want the full
page, just the partial
Could use a custom request header
If t...
PJAX Requests
If browser supports History API then intercept
links and make PJAX request
<a href=“/my-page/“ data-pjax>lin...
PJAX - Server
def myView(request):	
	 if request.headers[‘X-PJAX’]:	
	 	 return renderPartial()	
	 else:	
	 	 return rende...
PJAX Benefits
Fewer requests
Fast response
Reduced load on server
Bookmarkable URL
Degrades nicely
History API
Session History and Navigation API
Session History Browser Support
Traditional
http://website.com/index.html
Traditional
http://website.com/about.html

about

Unique resource has unique URL
Traditional + A JAX
http://website.com/index.html
Traditional + A JAX
http://website.com/index.html

about

Unique resource has shared URL
PushState + A JAX
http://website.com/index.html
PushState + A JAX
http://website.com/about.html

about

Unique resource has unique URL again
PushState
var stateObj, title, url;	
stateObj = {name: "fred"}	
url = "/fred";	
history.pushState(stateObj, title, url);
PushState
www.bbc.co.uk/news/

www.bbc.co.uk/fred

www.bbc.co.uk

Update the UI e.g. via ajax

{}
PopState Event
window.onpopstate = function(e) {	
	 console.log(e.state);	
}
PopState Event
the popState event is fired when you go back
and forward in the browser history
the state object assigned to...
PopState
www.bbc.co.uk/news/

www.bbc.co.uk/fred

www.bbc.co.uk

{}
Demo
Master - Detail with PJAX
Visual Cues
Visual Cues
Browsers have traditionally given visual cues
More power for developers (A JAX, History API)
Remember to keep ...
https://github.com/defunkt/jquery-pjax
$(document).on('pjax:send', function() {	
$('#loading').show()	
})	
$(document).on('pjax:complete', function() {	
$('#load...
PJAX
In the wild
PJAX - Who’s using it?
https://blog.twitter.com/2012/
improving-performance-on-twittercom
http://www.youtube.com/watch?v=hrZl_EQUbRQ
http://bit.ly/1hG3GTi
Backbone.js
Demo 3

Nesting Views
& Modals
Event Delegation &
Element Lifetime
Element Lifetime
Long lifetime (container)

Short lifetime
(view)

Short lifetime
(view)
Event Delegation
Delegate events to elements with a long lifetime
Events fired on newly inserted HTML bubble up
to containe...
Event Delegation (jQuery)

$(container).on(‘click’, ‘a[data-pjax]’, function(){	
	

do_something();	

});
HATEOAS
Hypermedia As The Engine Of Application State
Sport Link
What if there were no links
And instead, the BBC published a document detailing
URL’s of all their pages
+

BBC WEBSITE
BBC WEBSITE
URLS
BBC WEBSITE
URLS
!
URLS
!
VERSION 1.0
!
VERSION 2.0
VERSION 3.0
Don’t cook URLs on the
client, instead use the URLS
provided by the server
Decouples the client from the server
Demo 4

Discoverability
(HATEOAS)
Animation &
the Back Button
Animation
Feedback for the user is vital
Helps to suggest the behaviour of the back button
Helps to suggest available touc...
Demo 5

Animation
Animation

Spotify Web Player
Twitter App
Back Button
http://www.xkcd.com/1309/
http://www.reddit.com/r/programming/comments/
1uou3g/please_respect_the_back_button/
Epistemic Action
Demo 6

Push or Replace
Push or Replace
history.pushState vs history.replaceState
Is this a new state or are we just altering the
existing state?
...
ReplaceState
some potential use cases
Modal dialogues - users probably don't expect
the back button to undo the modal
Sett...
Staying In Sync
With The Server
Staying In Sync
With The Server
PJAX makes updating a part of the page easy
What about other representations of the same
e...
Assign URLs
to components

/image/58/panel/
/image/57/panel/
/image/56/panel/
Demo 7

Staying In Sync
With The Server
Staying In Sync
With The Server

Pros: Master and detail view stay in sync
Cons: making multiple requests for content
Staying In Sync
With The Server
How can we make a single request?
Server-Sent Events
Send HTML in JSON
Generic approach to...
Staying In Sync
With The Server
{	
	 “content”: [	
	 	 “div.thing”: “<p>content</p>”,	
	 	 “div.related”: “<p>related cont...
Staying In Sync
With The Server
Sending HTML/JSON could work but lots of
benefits of using SSE:
Uses Traditional HTTP
Autom...
Summary
PJAX - PushState+A JAX, URLs are important in modern JS heavy
apps
HATEOAS - decoupling client from server
Element...
Thanks
Questions
James Da Costa
@jamesdacosta

james@bright-interactive.com
jamesdacosta.com
Hybrid Web Applications
Hybrid Web Applications
Hybrid Web Applications
Hybrid Web Applications
Hybrid Web Applications
Upcoming SlideShare
Loading in …5
×

Hybrid Web Applications

4,774 views

Published on

Can traditional document-based applications compete with the user experience frameworks such as Ember & Angular are known for?

Published in: Technology

Hybrid Web Applications

  1. 1. Hybrid Web Applications with PJAX & HATEOAS James Da Costa @jamesdacosta
 james@bright-interactive.com jamesdacosta.com
  2. 2. 1885 2014
  3. 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. 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. 5. Is there another way? Retain server-side development environment Fluid & engaging UX (like modern SPAs) Not learn a big client-side framework
  6. 6. Imagebase - Upload, tag, and edit images
  7. 7. Toolset Django + Backbone.js
  8. 8. Backbone Models for managing data / syncing with server ! Router wrapper around History API
  9. 9. Demos The Old School Application PJAX & History API Nesting Views & Modals Discoverability (HATEOAS) Animation Push or Replace Staying In Sync
  10. 10. Demo 1 The Old School Application
  11. 11. Basic PJAX & History API
  12. 12. PJAX PushState + A JAX
  13. 13. Normal vs PJAX server Browser makes normal request Server responds with full HTML document Normal Request Browser
  14. 14. Normal vs PJAX Browser makes PJAX request and updates location bar Server responds with partial HTML document server PJAX Request Browser
  15. 15. jQuery-PJAX https://github.com/defunkt/jquery-pjax
  16. 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. 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. 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. 19. PJAX - Server def myView(request): if request.headers[‘X-PJAX’]: return renderPartial() else: return renderLayout()
  20. 20. PJAX Benefits Fewer requests Fast response Reduced load on server Bookmarkable URL Degrades nicely
  21. 21. History API Session History and Navigation API
  22. 22. Session History Browser Support
  23. 23. Traditional http://website.com/index.html
  24. 24. Traditional http://website.com/about.html about Unique resource has unique URL
  25. 25. Traditional + A JAX http://website.com/index.html
  26. 26. Traditional + A JAX http://website.com/index.html about Unique resource has shared URL
  27. 27. PushState + A JAX http://website.com/index.html
  28. 28. PushState + A JAX http://website.com/about.html about Unique resource has unique URL again
  29. 29. PushState var stateObj, title, url; stateObj = {name: "fred"} url = "/fred"; history.pushState(stateObj, title, url);
  30. 30. PushState www.bbc.co.uk/news/ www.bbc.co.uk/fred www.bbc.co.uk Update the UI e.g. via ajax {}
  31. 31. PopState Event window.onpopstate = function(e) { console.log(e.state); }
  32. 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
  33. 33. PopState www.bbc.co.uk/news/ www.bbc.co.uk/fred www.bbc.co.uk {}
  34. 34. Demo Master - Detail with PJAX
  35. 35. Visual Cues
  36. 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
  37. 37. https://github.com/defunkt/jquery-pjax
  38. 38. $(document).on('pjax:send', function() { $('#loading').show() }) $(document).on('pjax:complete', function() { $('#loading').hide() })
  39. 39. PJAX In the wild
  40. 40. PJAX - Who’s using it?
  41. 41. https://blog.twitter.com/2012/ improving-performance-on-twittercom
  42. 42. http://www.youtube.com/watch?v=hrZl_EQUbRQ
  43. 43. http://bit.ly/1hG3GTi
  44. 44. Backbone.js
  45. 45. Demo 3 Nesting Views & Modals
  46. 46. Event Delegation & Element Lifetime
  47. 47. Element Lifetime Long lifetime (container) Short lifetime (view) Short lifetime (view)
  48. 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
  49. 49. Event Delegation (jQuery) $(container).on(‘click’, ‘a[data-pjax]’, function(){ do_something(); });
  50. 50. HATEOAS Hypermedia As The Engine Of Application State
  51. 51. Sport Link
  52. 52. What if there were no links And instead, the BBC published a document detailing URL’s of all their pages
  53. 53. + BBC WEBSITE BBC WEBSITE URLS BBC WEBSITE URLS ! URLS ! VERSION 1.0 ! VERSION 2.0 VERSION 3.0
  54. 54. Don’t cook URLs on the client, instead use the URLS provided by the server Decouples the client from the server
  55. 55. Demo 4 Discoverability (HATEOAS)
  56. 56. Animation & the Back Button
  57. 57. 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
  58. 58. Demo 5 Animation
  59. 59. Animation Spotify Web Player Twitter App
  60. 60. Back Button
  61. 61. http://www.xkcd.com/1309/
  62. 62. http://www.reddit.com/r/programming/comments/ 1uou3g/please_respect_the_back_button/
  63. 63. Epistemic Action
  64. 64. Demo 6 Push or Replace
  65. 65. 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
  66. 66. 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
  67. 67. Staying In Sync With The Server
  68. 68. 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
  69. 69. Assign URLs to components /image/58/panel/ /image/57/panel/ /image/56/panel/
  70. 70. Demo 7 Staying In Sync With The Server
  71. 71. Staying In Sync With The Server Pros: Master and detail view stay in sync Cons: making multiple requests for content
  72. 72. 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
  73. 73. Staying In Sync With The Server { “content”: [ “div.thing”: “<p>content</p>”, “div.related”: “<p>related content</p>” ] }
  74. 74. 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
  75. 75. 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
  76. 76. Thanks Questions James Da Costa @jamesdacosta
 james@bright-interactive.com jamesdacosta.com

×