81
Hybrid Web Applications with PJAX & HATEOAS James Da Costa @jamesdacosta [email protected] jamesdacosta.com

Hybrid Web Applications

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Hybrid Web Applications

Hybrid Web Applications with PJAX & HATEOAS

James Da Costa

@jamesdacosta [email protected]

jamesdacosta.com

Page 2: Hybrid Web Applications

1885

2014

Page 3: Hybrid Web Applications

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

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

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

Imagebase - Upload, tag, and edit images

Page 7: Hybrid Web Applications

ToolsetDjango + Backbone.js

Page 8: Hybrid Web Applications

BackboneModels

for managing data / syncing with server

!

Router wrapper around History API

Page 9: Hybrid Web Applications

DemosThe Old School Application

PJAX & History API

Nesting Views & Modals

Discoverability (HATEOAS)

Animation

Push or Replace

Staying In Sync

Page 10: Hybrid Web Applications

The Old School Application

Demo 1

Page 11: Hybrid Web Applications

Basic PJAX & History API

Page 12: Hybrid Web Applications

PJAXPushState + A JAX

Page 13: Hybrid Web Applications

Normal vs PJAX

Browser makes normal request

Server responds with full HTML document

server

Browser

Normal Request

Page 14: Hybrid Web Applications

Normal vs PJAX

Browser makes PJAX request and updates

location bar

Server responds with partial HTML

document

server

Browser

PJAX Request

Page 15: Hybrid Web Applications

jQuery-PJAX

https://github.com/defunkt/jquery-pjax

Page 16: Hybrid Web Applications

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

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

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

PJAX - Serverdef myView(request):

if request.headers[‘X-PJAX’]:

return renderPartial()

else:

return renderLayout()

Page 20: Hybrid Web Applications

PJAX Benefits

Fewer requests

Fast response

Reduced load on server

Bookmarkable URL

Degrades nicely

Page 21: Hybrid Web Applications

History APISession History and Navigation API

Page 22: Hybrid Web Applications

Session History Browser Support

Page 23: Hybrid Web Applications

Traditionalhttp://website.com/index.html

Page 24: Hybrid Web Applications

Traditionalhttp://website.com/about.html

about

Unique resource has unique URL

Page 25: Hybrid Web Applications

Traditional + A JAXhttp://website.com/index.html

Page 26: Hybrid Web Applications

Traditional + A JAXhttp://website.com/index.html

about

Unique resource has shared URL

Page 27: Hybrid Web Applications

PushState + A JAXhttp://website.com/index.html

Page 28: Hybrid Web Applications

PushState + A JAXhttp://website.com/about.html

about

Unique resource has unique URL again

Page 29: Hybrid Web Applications

PushState

var stateObj, title, url;

stateObj = {name: "fred"}

url = "/fred";

history.pushState(stateObj, title, url);

Page 30: Hybrid Web Applications

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

PopState Event

window.onpopstate = function(e) {

console.log(e.state);

}

Page 32: Hybrid Web Applications

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

PopState

www.bbc.co.uk

www.bbc.co.uk/fred

www.bbc.co.uk/news/

{}

Page 34: Hybrid Web Applications

DemoMaster - Detail with PJAX

Page 35: Hybrid Web Applications

Visual Cues

Page 36: Hybrid Web Applications

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 37: Hybrid Web Applications

https://github.com/defunkt/jquery-pjax

Page 38: Hybrid Web Applications

$(document).on('pjax:send', function() {

$('#loading').show()

})

$(document).on('pjax:complete', function() {

$('#loading').hide()

})

Page 39: Hybrid Web Applications

PJAXIn the wild

Page 40: Hybrid Web Applications

PJAX - Who’s using it?

Page 41: Hybrid Web Applications

https://blog.twitter.com/2012/improving-performance-on-twittercom

Page 42: Hybrid Web Applications

http://www.youtube.com/watch?v=hrZl_EQUbRQ

Page 43: Hybrid Web Applications

http://bit.ly/1hG3GTi

Page 44: Hybrid Web Applications

Backbone.js

Page 45: Hybrid Web Applications

Nesting Views & Modals

Demo 3

Page 46: Hybrid Web Applications

Event Delegation & Element Lifetime

Page 47: Hybrid Web Applications

Element Lifetime

Short lifetime (view)

Short lifetime (view)

Long lifetime (container)

Page 48: Hybrid Web Applications

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

Event Delegation (jQuery)

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

do_something();

});

Page 50: Hybrid Web Applications

HATEOASHypermedia As The Engine Of Application State

Page 51: Hybrid Web Applications
Page 52: Hybrid Web Applications
Page 53: Hybrid Web Applications

Sport Link

Page 54: Hybrid Web Applications

What if there were no linksAnd instead, the BBC published a document detailing

URL’s of all their pages

Page 55: Hybrid Web Applications

+BBC WEBSITE

URLS !

VERSION 1.0

BBC WEBSITE URLS

!VERSION 2.0

BBC WEBSITE URLS

!VERSION 3.0

Page 56: Hybrid Web Applications

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

Discoverability (HATEOAS)

Demo 4

Page 58: Hybrid Web Applications

Animation & the Back Button

Page 59: Hybrid Web Applications

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

Animation

Demo 5

Page 61: Hybrid Web Applications

Animation

Spotify Web Player

Twitter App

Page 62: Hybrid Web Applications

Back Button

Page 63: Hybrid Web Applications
Page 64: Hybrid Web Applications

http://www.xkcd.com/1309/

Page 65: Hybrid Web Applications
Page 66: Hybrid Web Applications

http://www.reddit.com/r/programming/comments/1uou3g/please_respect_the_back_button/

Page 67: Hybrid Web Applications
Page 69: Hybrid Web Applications

Push or Replace

Demo 6

Page 70: Hybrid Web Applications

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

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

Staying In Sync With The Server

Page 73: Hybrid Web Applications

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

Assign URLs to components

/image/58/panel/

/image/57/panel/

/image/56/panel/

Page 75: Hybrid Web Applications

Staying In Sync With The Server

Demo 7

Page 76: Hybrid Web Applications

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

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

Staying In Sync With The Server

{

“content”: [

“div.thing”: “<p>content</p>”,

“div.related”: “<p>related content</p>”

]

}

Page 79: Hybrid Web Applications

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

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

Page 81: Hybrid Web Applications

ThanksQuestions

James Da Costa

@jamesdacosta [email protected]

jamesdacosta.com