[whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Aryeh Gregor
On Thu, Oct 15, 2009 at 3:49 AM, Nelson Menezes
flying.mushr...@gmail.com wrote:
 As an aside, there is a reason why AJAX has become so popular over the
 past few years: it solves the specific UI-reset issue that is inherent
 in full-page refreshes.

I'm trying to think what a solution to this would look like.  Maybe
something like:

static id=fooSome stuff that doesn't change on page load.../static
Changeable page content
static id=barSome more stuff that doesn't change.../static

The semantics would be that when the browser loaded the new page, it
would do something like

1) Retrieve the URL.
2) Start parsing the new page.  When the time comes to clear the
screen so it can be redrawn for the new page, leave any static
elements untouched, so they don't flicker or vanish.
3) When parsing the page, if a static element is reached that has
the same id as a static element that was on the old page, ignore the
contents of the new one.  Instead, move the old static element to
the position of the new one, copying its DOM.  If possible, this
shouldn't cause the visible static element to flicker or be redrawn,
if it's visible.  There should be some reasonable de facto or de jure
conditions where no-flicker is guaranteed, e.g., all applicable styles
are the same and the element is absolutely positioned relative to the
body.

As an added optimization, the browser could send an HTTP request
header like Static-IDs containing a list of the IDs of all static
elements currently on the page, so that the server can just leave
those empty.  A dynamic id=foo tag might be useful too, to indicate
that specific parts of a static element might indeed change -- in
this case the static element might have to be redrawn, but only once
the new dynamic element was fully parsed, not before.

I doubt this is suitable for HTML5, given how far along that is, but
it might be interesting to consider anyway.  Does the idea sound
interesting to anyone else?


Re: [whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Markus Ernst

Aryeh Gregor schrieb:

On Thu, Oct 15, 2009 at 3:49 AM, Nelson Menezes
flying.mushr...@gmail.com wrote:

As an aside, there is a reason why AJAX has become so popular over the
past few years: it solves the specific UI-reset issue that is inherent
in full-page refreshes.


I'm trying to think what a solution to this would look like.  Maybe
something like:

static id=fooSome stuff that doesn't change on page load.../static
Changeable page content
static id=barSome more stuff that doesn't change.../static


Interesting idea! Anyway it introduces some consistency problems to 
solve, e.g.:


Page1.html contains:

static id=fooI eat meat/static

and links to page2.html, which contains:

static id=fooI am a vegetarian/static

So page2.html looks different whether it is called from the link in 
page1.html, or directly via a bookmark, external link, or manual URI input.


This could be solved if static elements have no content on their own, 
but retrieve it from an external source. The identifyer is then not the 
id attribute, but the source. This could be done with a src attribute on 
the static element. But I assume an easier implementation would be 
adding a static attribute for the iframe element, indicating that 
the iframe contents should not be reloaded.


--
Markus


Re: [whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Tab Atkins Jr.
On Fri, Oct 16, 2009 at 6:16 AM, Markus Ernst derer...@gmx.ch wrote:
 Aryeh Gregor schrieb:

 On Thu, Oct 15, 2009 at 3:49 AM, Nelson Menezes
 flying.mushr...@gmail.com wrote:

 As an aside, there is a reason why AJAX has become so popular over the
 past few years: it solves the specific UI-reset issue that is inherent
 in full-page refreshes.

 I'm trying to think what a solution to this would look like.  Maybe
 something like:

 static id=fooSome stuff that doesn't change on page load.../static
 Changeable page content
 static id=barSome more stuff that doesn't change.../static

 Interesting idea! Anyway it introduces some consistency problems to solve,
 e.g.:

 Page1.html contains:

 static id=fooI eat meat/static

 and links to page2.html, which contains:

 static id=fooI am a vegetarian/static

 So page2.html looks different whether it is called from the link in
 page1.html, or directly via a bookmark, external link, or manual URI input.

Nod.  This seems like a big problem.

 This could be solved if static elements have no content on their own, but
 retrieve it from an external source. The identifyer is then not the id
 attribute, but the source. This could be done with a src attribute on the
 static element. But I assume an easier implementation would be adding a
 static attribute for the iframe element, indicating that the iframe
 contents should not be reloaded.

As well, if iframe is reused, it should probably automatically be
iframe seamless so that all navigation applies to the upper page, it
grabs styles from the upper page, etc.  (Or perhaps it should just be
recommended that iframe static seamless be used in most
circumstances.)

The iframe solution is also somewhat better wrt scripting the
content inside.  If you're trying not to redraw anything in static,
what happens to scripts that have added listeners and such to the
content?  (Frex, to implement an accordion or treeview.)  The original
page is going away, and you don't want to accidentally apply the
listeners multiple times.  Using iframes, you can do the scripting
in the framed page, so nothing goes away between pageloads or tries to
apply itself multiple times.

~TJ


Re: [whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Aryeh Gregor
On Fri, Oct 16, 2009 at 7:16 AM, Markus Ernst derer...@gmx.ch wrote:
 Interesting idea! Anyway it introduces some consistency problems to solve,
 e.g.:

 Page1.html contains:

 static id=fooI eat meat/static

 and links to page2.html, which contains:

 static id=fooI am a vegetarian/static

 So page2.html looks different whether it is called from the link in
 page1.html, or directly via a bookmark, external link, or manual URI input.

Well, certainly impose a same-origin restriction on preservation of
static.  Then it would just be a problem of one site being
inconsistent with itself.  But I don't think this is a bug, it's a
feature.  One of the major advantages of frames is you can manipulate
each piece independently, and not have your changes lost on
navigation.  If a script changes the contents of the static after it
was created, those changes *should* be required to persist on page
load.

An alternative idea would be to dispense with id's, and key off a hash
of the literal string contents of the static instead, in the
serialized document passed over the wire.  Bandwidth savings could
then be obtained using static hash=.../static or some similar
syntax, with the UA passing the hashes instead of id's in a header.
This way, the element would auto-update if the contents changed on the
server side, but not on the client side.

On the other hand, if they did change it would lose all the user's
changes, if any.  But you can't rely on the changes being present
after page reload anyway, if the element has been changed, so maybe
this is noncritical.  It depends what exactly this would be used for.

The obvious use case here would just be to keep navigation elements
fixed.  For instance, on http://en.wikipedia.org/wiki/, most of div
id=column-one could be static.  (With a few exceptions, like div
id=p-cactions.)  Navigation tends not to be very interact-able, so
reloading it and throwing out client-side changes would be fine if it
changes on the server side.

A slightly different use-case would be a dynamic application like
Gmail, rewritten without AJAX.  The bar on the left contains things
like Inbox (2), which are updated by script.  In this case, if new
contents were loaded from the server, the server or script would
promptly fill in the appropriate numbers and so on.  So again, this
use-case doesn't seem to care much if changes are thrown out.

Another case to consider is where you have a tree or something that
gets uncollapsed depending on what page you're on.  This seems like a
case where you'd actually want something slightly different: the new
version should load, just without flickering.  Perhaps a cruder
solution would be useful, which doesn't affect display of the new page
but only how new elements get loaded -- specifically, allowing a mix
of content from the old and new page to exist until the new page is
fully painted.  I'm not sure how that would work.  The sort of
compression I suggested in static could probably be better handled
by SDCH or something.

 This could be solved if static elements have no content on their own, but
 retrieve it from an external source. The identifyer is then not the id
 attribute, but the source. This could be done with a src attribute on the
 static element. But I assume an easier implementation would be adding a
 static attribute for the iframe element, indicating that the iframe
 contents should not be reloaded.

I don't like this solution, because it complicates things for authors.
 You have to make separate pages for each interface widget, and it
entails more HTTP requests.  It's also not backwards-compatible --
you'll often get a big degradation in behavior if you use this in a
browser that doesn't support iframe seamless.  static as I
envisioned it can be dropped into existing pages without requiring
them to be broken into separate files, or risking compatibility
problems.


Re: [whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Tab Atkins Jr.
On Fri, Oct 16, 2009 at 8:50 AM, Aryeh Gregor simetrical+...@gmail.com wrote:
 On Fri, Oct 16, 2009 at 7:16 AM, Markus Ernst derer...@gmx.ch wrote:
 Interesting idea! Anyway it introduces some consistency problems to solve,
 e.g.:

 Page1.html contains:

 static id=fooI eat meat/static

 and links to page2.html, which contains:

 static id=fooI am a vegetarian/static

 So page2.html looks different whether it is called from the link in
 page1.html, or directly via a bookmark, external link, or manual URI input.

 Well, certainly impose a same-origin restriction on preservation of
 static.  Then it would just be a problem of one site being
 inconsistent with itself.  But I don't think this is a bug, it's a
 feature.  One of the major advantages of frames is you can manipulate
 each piece independently, and not have your changes lost on
 navigation.  If a script changes the contents of the static after it
 was created, those changes *should* be required to persist on page
 load.

Indeed, script changes should persist.  The problem he was
highlighting, though, was the fact that a 'site bug' like that would
be very easy to have happen accidentally.  It could even go unnoticed
by the site developers, if they always come in through the front page
and the content is correct there - only users following search engine
links or bookmarks deep into the site would see the obsolete content,
and it would *never go away* during that browsing session.

This error seems like it would be very easy to make.

As well, this still doesn't answer the question of what to do with
script links between the static content and the original page, like
event listeners placed on content within the static.  Do they get
preserved?  How would that work?  If they don't, then some of the
benefit of 'static' content is lost, since it will be inoperable for a
moment after each pageload while the JS reinitializes.

 An alternative idea would be to dispense with id's, and key off a hash
 of the literal string contents of the static instead, in the
 serialized document passed over the wire.  Bandwidth savings could
 then be obtained using static hash=.../static or some similar
 syntax, with the UA passing the hashes instead of id's in a header.
 This way, the element would auto-update if the contents changed on the
 server side, but not on the client side.

I would hope that authors never did that!  That means that if a user
deeplinks straight into the site, they'll get the empty element.  The
hash won't help them, since it's their first pageview.  *Hopefully*
they'll swing by a page that has the actual contents and the hashfail
would trigger an update, but that's not a guarantee, and in the
meantime they have an empty element there.

 On the other hand, if they did change it would lose all the user's
 changes, if any.  But you can't rely on the changes being present
 after page reload anyway, if the element has been changed, so maybe
 this is noncritical.  It depends what exactly this would be used for.

I think being updated is more important than persisting changes to
(now out-of-date) content.

 A slightly different use-case would be a dynamic application like
 Gmail, rewritten without AJAX.  The bar on the left contains things
 like Inbox (2), which are updated by script.  In this case, if new
 contents were loaded from the server, the server or script would
 promptly fill in the appropriate numbers and so on.  So again, this
 use-case doesn't seem to care much if changes are thrown out.

One of the big reasons Gmail is so AJAXy is because of the heavy
script lifting it has to do on each page load.  AJAX lets them persist
the script while updating the content.  static wouldn't help with
that.

 Another case to consider is where you have a tree or something that
 gets uncollapsed depending on what page you're on.  This seems like a
 case where you'd actually want something slightly different: the new
 version should load, just without flickering.  Perhaps a cruder
 solution would be useful, which doesn't affect display of the new page
 but only how new elements get loaded -- specifically, allowing a mix
 of content from the old and new page to exist until the new page is
 fully painted.  I'm not sure how that would work.  The sort of
 compression I suggested in static could probably be better handled
 by SDCH or something.

The new page can just js-manipulate the static element.  If you're not
happy with that, then you really *do* need the bits to reload with the
page, and shouldn't be using static.

 This could be solved if static elements have no content on their own, but
 retrieve it from an external source. The identifyer is then not the id
 attribute, but the source. This could be done with a src attribute on the
 static element. But I assume an easier implementation would be adding a
 static attribute for the iframe element, indicating that the iframe
 contents should not be reloaded.

 I don't like this solution, because it complicates 

Re: [whatwg] No interface flicker across page loads, without JavaScript (was: framesets)

2009-10-16 Thread Aryeh Gregor
On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. jackalm...@gmail.com wrote:
 Indeed, script changes should persist.  The problem he was
 highlighting, though, was the fact that a 'site bug' like that would
 be very easy to have happen accidentally.  It could even go unnoticed
 by the site developers, if they always come in through the front page
 and the content is correct there - only users following search engine
 links or bookmarks deep into the site would see the obsolete content,
 and it would *never go away* during that browsing session.

 This error seems like it would be very easy to make.

Hmm.  Maybe.

 As well, this still doesn't answer the question of what to do with
 script links between the static content and the original page, like
 event listeners placed on content within the static.  Do they get
 preserved?  How would that work?  If they don't, then some of the
 benefit of 'static' content is lost, since it will be inoperable for a
 moment after each pageload while the JS reinitializes.

Script links should be preserved somehow, ideally.  I would like to
see this be along the lines of AJAX reload of some page content,
without JavaScript and with automatically working URLs.

 I would hope that authors never did that!  That means that if a user
 deeplinks straight into the site, they'll get the empty element.  The
 hash won't help them, since it's their first pageview.  *Hopefully*
 they'll swing by a page that has the actual contents and the hashfail
 would trigger an update, but that's not a guarantee, and in the
 meantime they have an empty element there.

I meant in conjunction with an HTTP header the browser would send,
like Static-Hashes, that contains the hashes of all known static
elements.  This is like the Static-IDs that I described in my first
post.  The idea would be that a script could chop out the unneeded
parts on a per-request basis.  However, I think SDCH is a better
solution here.

 I think being updated is more important than persisting changes to
 (now out-of-date) content.

It depends on how important the changes are.  If for some reason you
have a textarea in static, and the user has entered tons of text,
saving it is fairly important.  Although you should be able to hit
back to retrieve it, actually, so maybe not *that* important.

 One of the big reasons Gmail is so AJAXy is because of the heavy
 script lifting it has to do on each page load.  AJAX lets them persist
 the script while updating the content.  static wouldn't help with
 that.

That's why script needs to persist.  My initial proposal doesn't
handle that well at all.

 Only for the first pageload.

The first page load is by far the most important.

 And separate pages for each interface widget isn't bad.  Heck, it's
 easier to maintain with everything self-contained.

Handling everything in one request is *much* simpler from the POV of
server-side scripting.  If it's separate requests, you can typically
only communicate between them if you a database of some kind.  That's
a real pain.  You're running several instances of the script which all
need to produce consistent output, and that's a lot harder than if
it's just one instance.  What if different cookies end up being sent
to different frames, for instance?  That's very possible if the user
gets logged out at some point, say.  The new page load needs to be
able to invalidate the other parts of the page somehow.

 True.  Minting a new element might be a better deal here, but having
 it inherit much of the semantics of iframe seamless.  Then you can
 have it contain fallback content for browsers that don't implement
 static, and use @src for browsers that do.  That would also allow us
 to bypass any of the iframe complications that might unnecessarily
 complicate use or implementation.

I still don't like the requirement for multiple pages.  It might not
be a big deal if you're dealing mainly with static content, but for
complex server-side scripts I think it would be a real pain.

So, here's a preliminary description of a use-case.  I'm not sure it's sane yet.

Use Case: A page should be able to instruct that when a user follows a
link, only part of the page is reloaded, while the rest stays fixed.

Requirements:
1) Little to no JavaScript should be required.  Large JavaScript
frameworks should not be necessary to get basic persistence of
interface state.

2) Static parts of the page should not have their state discarded,
either script-related state (e.g., registered event handlers) or other
state (e.g., user-entered text).

3) It should be possible for user agents to implement the feature so
that the static parts of the page don't flicker or jump around unless
they've actually changed.  (This might or might not be an actual
conformance requirement, but it should be possible for them to do it
if they want.)

4) It should be possible to easily attach this to an existing set of
static pages, or JavaScript-light pages produced by a web application.