32
State & Ajax Oil and Water Application State Browser State Browbeating paul reinheimer php|architect Maintaining application state within an asynchronous application The back button isn’t yours, stop breaking it. Also Bookmarks! (Uses YUI) You’ve been bad. Sorry :(

State And Ajax Zend Con

  • Upload
    zendcon

  • View
    5.614

  • Download
    0

Embed Size (px)

DESCRIPTION

This talk will examine the two greatest problems in Ajax development (except for that pesky browser issue): Exactly what that “Asynchronous” word means, what problems it creates, and how they can be effectively managed, next the YUI Browser History object will be examined, finally handing control of Ajax applications back to the user via their familiar back button.

Citation preview

Page 1: State And Ajax   Zend Con

State & AjaxOil and Water

Application State Browser State Browbeating

paul reinheimerphp|architect

Maintaining application state within an asynchronous

application

The back button isn’t yours, stop breaking it.

Also Bookmarks!(Uses YUI)

You’ve been bad. Sorry :(

Page 2: State And Ajax   Zend Con

>whoami

๏ Hi!

๏ Paul Reinheimer

๏ Full time instructor for php|architect

๏ Author Professional Web APIs with PHP

๏ P3 Podcast

๏ Acquisition editor for C7Y Articles

๏ Doc team member php.net

๏ Some other stuff

Page 3: State And Ajax   Zend Con

Talk Synopsis

๏ Ajax is really nifty

๏ It has two big problems: Application state in an asynchronous world and browser history.

๏ Application State

๏ When you make sequential requests, they might come back in a different order

๏ Browser State

๏ We broke the back button, it wasn’t ours. We have to give the ball back.

Page 4: State And Ajax   Zend Con

Why you should care

๏ Customers abandon shopping carts and experiences all the time, both traditionally (brick & mortar).

๏ They abandon these experiences for external reasons (from a technology prospective) like cost, time, availability, suitability.

๏ They also abandon these experiences when sites don’t work, break, mis-behave, or become too difficult to use.

Page 5: State And Ajax   Zend Con

Caring is Counting

๏ Ensure your entire development team is on board for providing consistent Ajax experiences that meet user expectations.

๏ Build from the start. Don’t add in a week before go-live. Untested = Fail.

๏ Websites that continuously provide excellent user experiences are more likely to be visited, re-visited, shared, and praised.

๏ Websites that have the above are more likely to achieve goals.

the cash

Page 6: State And Ajax   Zend Con

Application State

๏ If you ask someone what Ajax stands for, they might answer it doesn’t stand for anything, or they might say “Asynchronous JavaScript And XML”

๏ Asynchronous means that you’re welcome to send requests one after another, but they’re not guaranteed to return in that order.

๏ If your application isn’t ready to handle those responses returning in jumbled order, it isn’t really ready to go live.

Page 7: State And Ajax   Zend Con

Asynchronous

๏ Unlike PHP JavaScript can be approached as an event based language: users can initiate multiple events in rapid succession

๏ Depending on routing, and script length they can take effect on the server, or return in differing order.

๏ During testing you may initiate actions A -> B -> C, your users however may have other orders in mind.

Page 8: State And Ajax   Zend Con

Does it matter๏ Yes!

๏ Selecting a country in a drop dow list

๏ Cambodia

๏ Cameroon

๏ Canada

๏ Failing a login then correcting

๏ Muscle Memory

๏ Logging in, then activating another control that behaves differently depending on your login state

๏ Users are impatient

Page 10: State And Ajax   Zend Con

Not always a problem

๏ This isn’t a problem you need to solve every single time, it depends on your application and the specific action. Actions like queuing like canceling can simply slow your application down.

Page 11: State And Ajax   Zend Con

Solutions?

๏ Several Possible Solutions:

๏ Queue Queries against the server

๏ http://example.preinheimer.com/ajaxCourse/blockingLatency.php

๏ Cancel old requests

๏ If the information is now irrelevant, toss it

๏ Maintain state

๏ Know what your application is doing, and manage it.

Page 12: State And Ajax   Zend Con

Choosing a Solution

๏ Failed Login Attempts

๏ Cancel old requests

๏ Selecting a country

๏ Queueing or Canceling

๏ Logging in, then activating another control

๏ Block on other actions

Page 13: State And Ajax   Zend Con

Multiple Solutions

๏ Some pages may involve multiple solutions, know how your page interacts with itself.

Page 14: State And Ajax   Zend Con

The server side catch

๏ Canceling requests can have repercussions on the server side script.

๏ Different languages handle it differently, We will concentrate on... PHP (selected randomly)

๏ What happens to a running PHP script when a user hits the stop button or a request is otherwise cancelled?

Page 15: State And Ajax   Zend Con

Ignore User Abort

๏ When a request is cancelled PHP really has no idea, there isn’t a communication mechanism in place for PHP to be informed, it just trudges on... Until it attempts to actually transmit data to the client, at which point it is terminated.

๏ Ignore User Abort (php.ini, and function) allows you to instruct PHP to continue execution while it lacks an output resource.

Page 16: State And Ajax   Zend Con

Application State

๏ Consider it

๏ Users are random

๏ Users are impatient, they click often and hard

๏ Touch screens on airplanes, worst idea ever

๏ We can give them what they want, we just need to ponder the real problems.

Page 17: State And Ajax   Zend Con

Browser State

๏ We broke the back button

๏ It wasn’t ours in the first place

๏ It really matters

๏ We Failed.

Page 18: State And Ajax   Zend Con

The Back Button

๏ Pre Ajax

๏ The Back button is a simple control that provides a perfect user safety net, it doesn’t matter what you do, what you click on, you can take it back with one click.

Page 19: State And Ajax   Zend Con

The Back ButtonWeb 2.0 Broke the Web

The back button is now either a simple undo of a previous action to a catastrophic reversal of one to many

different actions. That button may undo that selection you just made, or it may take you

back to the last page you were at before you logged in.

Stop breaking things!

Page 20: State And Ajax   Zend Con

The Back Button

๏ The Real Problem

๏ The Back Button is basically a stack, replaying URIs. Every time the URI changes the stack is pushed, when you hit back the stack is popped. When you change the page without changing the URI there’s no stack action.

Page 21: State And Ajax   Zend Con

The Web

๏ Okay, the web was broken already, browsers take a hand in that. Sure there’s this thing called HTML, and it has a spec, but no one understands what it actually means, if they do understand it, they “understand” it different than everyone else:

๏ Deprecated. This attribute sets the size of the font. Possible values:

๏ An integer between 1 and 7. This sets the font to some fixed size, whose rendering depends on the user agent. Not all user agents may render all seven sizes.

๏ A relative increase in font size. The value "+1" means one size larger. The value "-3" means three sizes smaller. All sizes belong to the scale of 1 to 7.

Page 22: State And Ajax   Zend Con

Not My Problem!

Not your problem?You still have to fix it

Page 23: State And Ajax   Zend Con

The Back Button

๏ Can This Even be solved?

๏ Yes

๏ The trick is those fancy mid page anchors that people used back when GeoCities was cool. index.html#heading

๏ The page doesn’t reload, but the browser counts it as a stack action.

Page 24: State And Ajax   Zend Con

BrowsersBrowser Suck, Internet

Explorer in particular, but they all suck at least a little.

You could spend the next several years of your life, lose

some hair, and cry a little (I cried a lot) to try and handle

differences, or you could use a library.

It’s not all your fault

Page 25: State And Ajax   Zend Con

YUI

๏ ... Or you could use Yahoo User Interface (YUI)

๏ Why Choose YUI

๏ Documentation!

๏ Browser History tool works really well

๏ Great videos

๏ Active Development

๏ Documentation

Page 26: State And Ajax   Zend Con

YUI - Tips

๏ Cheat Sheets

๏ Strip down examples to learn the ropes

๏ Save debugging files (multiple versions)

๏ Firebug

Page 27: State And Ajax   Zend Con

Browser History Object

๏ It’s kind of complicated, but it’s not their fault (browsers!)

๏ An iFrame is used to help internet explorer along, point it at a resource on the same server you’re going to use anyways.

๏ The resource needs to be initialized with a string, rather than an integer.

Page 28: State And Ajax   Zend Con

YUI Library: Browser History Manager 2008-2-19 v2.5

Getting Started with Browser History Manager

1. Required Markup

The Browser History Manager requires the following in-page markup:

<iframe id="yui-history-iframe" src="asset"></iframe>

<input id="yui-history-field" type="hidden">

1. The asset loaded in the IFrame must be in the same domain as the page (use a relative path for the src attribute to make sure of that)

2. The asset loaded in the IFrame does not have to be an HTML document. It can be an image for example (if you use an image that you also happen to use in your page, you will avoid an unnecessary round-trip, which is always good for performance)

3. This markup should appear right after the opening <body tag.

2. Module Registration and the register Method

Use the following code to register a module:

YAHOO.util.History.register(str module, str initial

state, fn callback[, obj associated object, b scope])

Arguments:

1. module: Arbitrary, non empty string identifying the module. 2. Initial state: Initial state of the module (corresponding to its earliest

history entry). YAHOO.util.History.getBookmarkedState may

be used to find out what this initial state is if the application was accessed via a bookmark.

3. callback: Function that will be called whenever the Browser History Manager detects that the state of the specified module has changed. Use this function to update the module’s UI accordingly.

4. associated object: Object to which your callback will have access; often the callback’s parent object.

5. scope: Boolean – if true, the callback runs in the scope of the associated object.

3. Using the onReady Method

Once you’ve registered at least one module, you should use the Browser History Manager's onReady method. In your handler, you should

initialize your module(s) based on their current state. Use the function YAHOO.util.History.getCurrentState to retrieve the current

state of your module(s).

YAHOO.util.History.onReady(function () { var currentState =

YAHOO.util.History.getCurrentState("module"); // Update UI of module to match current state });

4. Initializing the Browser History Manager

Before using the Browser History Manager, you must initialize it, passing in the id of the required HTML elements created in step 1:

YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");

Storing New History Entries: The navigate Method

Any registered module can create a new history entry at any time. Doing so creates a new “stop” to which the user can navigate to via the back/forward buttons and that can be bookmarked in the browser. You can create new history entries in your script using the navigate method.

YAHOO.util.History.navigate(str module, str new state);

Arguments:

1. module: Module identifier you used when you registered the module. 2. new state: String representing the new state of the module.

Note: The navigate method returns a Boolean indicating whether the new state was successfully stored. Note: The multiNavigate method allows you to change the state of several modules at once, creating a single history entry, whereas several calls to navigate would create several history entries.

A Sample Interaction

YAHOO.util.History Methods:

getBookmarkedState(str module) returns str bookmarked state

getCurrentState(str module) returns str

current state getQueryStringParameter(str param

name[, str query string]) returns str

param value initialize(str stateFieldId, str

histFrameId) navigate(str module, str state) returns

Boolean success multiNavigate(arr states) returns

Boolean success register(str module, str initial state, fn

callback[, obj associated object, b scope])

Dependencies

Browser History Manager requires the YAHOO Global Object and the Event Utility.

Page 30: State And Ajax   Zend Con

Browser State

๏ Fixing the back button returns essential control to your end users.

๏ Happy users buy products, tell friends, return to the site, all those exciting things.

Page 31: State And Ajax   Zend Con

Resources

๏ My Blog: http://blog.preinheimer.com/

๏ YUI: http://developer.yahoo.com/yui

๏ YUI Theater: http://developer.yahoo.com/yui/theater/

๏ Quirks Mode: http://www.quirksmode.org/

๏ Happy Bunny: http://www.jimbenton.com/

๏ Training: http://www.phparch.com

Page 32: State And Ajax   Zend Con

Special Thanks

๏ Yahoo!

๏ Great Tools, docs that don’t suck

๏ Firebug & Dragonfly

๏ Ajax life, worth living

๏ Audience

๏ Talking to yourself gets old somewhere into the third hour.