[whatwg] history.back()

Darin Fisher darin at chromium.org
Fri Jan 22 10:15:06 PST 2010


On Fri, Jan 22, 2010 at 2:08 AM, Ian Hickson <ian at hixie.ch> wrote:

> On Thu, 21 Jan 2010, Darin Fisher wrote:
> >
> > In WebKit, history.back() is currently implemented asynchronously.
>
> It's not clear to me what you mean by "asynchronously".
>
> Do you mean that the events fire asynchronously? That the Location object
> is updated asynchronously? That the decision about whether the call is a
> noop or not is fired asynchronously? That the navigation, if one is
> necessary, is done asynchronously? Are we talking about same-frame, or
> cross-frame? Same-origin, or cross-origin? Traversal from one entry in one
> document to another entry in the same document, or in another document?
>

To clarify:

history.{back,forward,go} begin by scheduling a task on the current thread
to run later.  From that task, the history traversal algorithm is executed.




>
> I made some demos to test this out, and it seems that IE8 behaves
> differently whether it's cross-frame or same-frame. I'd really rather we
> define this in a way that is consistent for all ways of invoking the API.
> It does the Location changes synchronously if invoked in-page, and
> asynchronously if the traversal affects another page.
>

That's very interesting.



>
> For simple cases, Firefox consistently does the Location change
> synchronously. Opera (10.x on Windows), Safari (4 for Windows), and Chrome
> do it async. But complicated cases make these descriptions simplistic.
>
>   http://www.hixie.ch/tests/adhoc/dom/level0/history/sync-vs-async/
>
>
> > IE however appears to implement history.back() asynchronously in all
> > cases just like newer versions of WebKit.
>
> That doesn't appear to be completely accurate.
>

I was only testing the cross frame case.  Thank you for testing more
thoroughly.



>
>
> > From a web compat perspective, it seems wise to match the behavior of
> > IE. It also has other benefits.
> >
> > Can we change the spec?
>
> Yes, but that won't make it async if the goal is to match IE.
>
>
> On Thu, 21 Jan 2010, Jonas Sicking wrote:
> >
> > Sounds good to me. Having all navigation be asynchronous I suspect would
> > have implementations benefits in Gecko too.
>
> It would be a reasonably minor change to the spec. I'm happy to go either
> way on this. The problem is I don't know exactly what "async" vs "sync"
> really means in this context, since the algorithms are quite complicated.
>
>
> On Thu, 21 Jan 2010, Olli Pettay wrote:
> >
> > And still one thing to test and specify;
> > if history.back()/forward() is asynchronous,
> > does that mean that loading start asynchronously,
> > or that entries are added asynchronously to session history?
> >
> > What should happen if a page calls:
> > history.back();
> > history.forward();
> >
> > What if the page calls:
> > history.back();
> > history.go(-2);
>
> Indeed. There are the kinds of questions I am curious about.
>
> Another is what should happen if a page goes back() past its fragment
> identifier entries, and then modifies the document or alerts the location?
> What location should it get? Which document should it mutate? (test 007)
>
> How about:
>
>   location.hash = 'a';
>   /* spin event loop */
>   history.back();
>   location.hash = 'b';
>   history.forward();
>   alert(location.hash);
>   /* spin event loop */
>   alert(location.hash);
>

It would be nice if the navigation and history traversal algorithms did not
proceed while the page is blocked on a modal alert.



>
> What does this alert? (test 008)
>
> How about:
>
>   location.hash = 'x';
>   location.hash = 'a';
>   /* spin event loop */
>   history.back();
>   /* spin event loop */
>   history.forward();
>   location.hash = 'b';
>   /* spin event loop */
>   history.back();
>   /* spin event loop */
>   alert(location.hash);
>
> What does this alert? (test 010)
>
>
> > And btw, some of the session history handling is anyway synchronous. Per
> > the current HTML5 draft calling document.open() adds a new entry to
> > session history immediately (IIRC, webkit is the only one which doesn't
> > support this).
>
> Another example is navigating to a fragment identifier, which in all
> browsers I tested changes the Location object immediately also.
>
>
> As I see it these are the criteria that we have to consider here in making
> a decision, in order of importance:
>
>  * Compatibility.
>   It seems that browsers are quite inconsistent here, and so it's likely
>   that we have some room to maneuver. Nobody has mentioned any
>   particular bugs in sites caused by implementing this one way or
>   another. I am not convinced that compatibility is a factor at this
>   point.
>
>  * Consistency for authors
>   I think whatever solution we come up with we should make sure it is
>   sane for authors. In this case, however, pretty much any model works,
>   so this doesn't really help decide what is best, so long as we are
>   consistent in how we specify and implement it.
>
>  * Implementation concerns
>   This may be the deciding factor, in particular due to the multiprocess
>   session history issues Darin raised.
>
>  * Specification sanity
>   I think we can probably make any model work in the spec, without even
>   much of a rewrite being needed. It's just a matter of saying when
>   things happen, for which the spec now has considerable infrastructure.
>
>
> Does anyone have any opinions on how the examples above should work? How
> should document.open() and location's setter interact with history.back()?
> Should navigation to fragment identifiers asynchronously set Location?
>

I think it would be risky to make navigation to fragment identifiers
asynchronously set Location.  All browsers do so synchronously today, so I
wouldn't be surprised to find that it matters.

I suspect that history.{back,forward,go} are not widely used, whereas
location="#foo" is probably used a lot.

One reason why history.{back,forward,go} may be underused is that there is
no sure fire way to know that you aren't at the beginning of session history
or at the end.  The browser only provides history.length.  It does not
provide a history.index, so you would have to keep track of where you are
manually.  That could be problematic, especially considering the page cache
feature of some browsers.



> Should Location be set synchronously but with the session history actually
> being updated asynchronously using a task, so that .back() and .forward()
> calls get interleaved with the Location setter?


I think this would be problematic in other cases.  Imagine this scenario:

location="#a";
pushState("b", "b", "#b");
location="#c";  // generates a synchronous popstate event




> Should document.open()
> synchronously clear the session history, or should it asynchronously queue
> a task and do it that way? Should we, instead of using tasks that could
> run much later (e.g. if the script has previously invoked a bunch of
> setTimeout(0)s), add a step to the event loop so that after each task, any
> history traversal that's been queued up gets processed immediately?
>

non-FIFO queuing makes me nervous ;-)

-Darin



>
> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20100122/8da34afd/attachment-0002.htm>


More information about the whatwg mailing list