[
https://issues.apache.org/jira/browse/TAP5-544?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12677728#action_12677728
]
Howard M. Lewis Ship commented on TAP5-544:
-------------------------------------------
This is working pretty well for FF, but doesn't work for IE. I'm having
trouble getting the original event to cancel inside Tapestry.waitForPage().
> Improve JavaScript handling to prevent the user from clicking Ajax-oriented
> links and forms before the page is "ready"
> ----------------------------------------------------------------------------------------------------------------------
>
> Key: TAP5-544
> URL: https://issues.apache.org/jira/browse/TAP5-544
> Project: Tapestry 5
> Issue Type: Improvement
> Components: tapestry-core
> Affects Versions: 5.1.0.1
> Reporter: Howard M. Lewis Ship
> Assignee: Howard M. Lewis Ship
>
> I think it's well time to open a discussion about Tapestry 5 and JavaScript.
> I think Tapestry is getting a large number of things right, but also a small
> number of things wrong. This is not a discussion about jQuery vs. Prototype
> (that's a separate area), but more about the behavior of Tapestry JavaScript,
> within the constrains of the browser.
> In standard usage, the JavaScript for a page is collected together and moved
> to the bottom of the page: first a series of <script> tags to load JavaScript
> libraries, then a single block of code to perform all kinds of
> initialization; this block executes, ultimately, when the page is fully
> loaded: after all HTML and JavaScript (but, depending on the browser, before
> all images have fully loaded).
> This is good and bad; the good part is that we are following Yahoo's
> performance guidelines: JavaScript at the bottom of the page, so it doesn't
> slow down rendering of the markup. However, this means that common
> practices, such as using the "javascript:" psuedo-scheme (i.e. <a
> src="javascript:...">) are not possible, since the referenced JavaScript
> would not have been loaded yet. In fact, many users must configure Tapestry
> to move the scripts back up to the top of the page (inside the <head>) to
> meet external demands (of third-party URL trackers and advertising solutions).
> Further, on a page that loads slowly (one that has a large number of external
> scripts, is accsessed via a slow-bandwidth pipe, or has a very complex
> layout), this means that JavaScript event handlers are not wired up until all
> JavaScript has been downloaded and parsed. The end result it that you can
> "outrace" Tapestry, click a link that should update a zone and get incorrect
> behavior or even a runtime exception. I actually see this when using Formo's
> time-tracking application from home through a slow pipe, exacerbated by
> HTTPS, where I get the error that "Block is not a valid response type". What
> should have been an Ajax request was processed instead as a traditional page
> render request, because the JavaScript was not ready.
> An earlier version of Tapestry 5 approached this problem by disabling the
> link components when the zone parameter was in use; that is, the href
> parameter was written out a "#", so the only way the link would be active is
> via an attached onclick event handler.
> This solution was weak, because there was no graceful degradation: clients
> without JavaScript would have a non-functioning application. Thus it was
> changed to render the href normally AND add an onclick event handler, which
> leads to the race conditions described above.
> What I really would like to see is the following:
> The page renders normally. If a user submits a form or clicks a link before
> all initialization code has executed, then a popup dialog will appear to
> inform the user that the page is still loading. When the load is complete,
> the message changes and the dialog fades out.
> Possibly, when a page is loading a more subtle floating "Loading ..." dialog
> would appear and disappear once the page is, in fact, loaded.
> What would it take to accomplish this?
> Firstly, JavaScript libraries would have to move (back) to the <head>,
> permanently, no configuration (well, short of replacing some internal
> services). We can't have inline javascript unless the javascript being
> referenced loads first. Hopefully, we'll be able to make up the performance
> difference (if measurable) with the future plans to minimize and combine
> JavaScript for the page. JavaScript initialization would still occur at the
> bottom.
> Next, Ajax-y links and forms would have something like
> onclick="javascript:Tapestry.waitForPageLoad();" written into their HTML;
> this would be the logic that would raise the dialog if you clicked a link too
> early.
> Once the Prototype dom:loaded event is fired, and all the normal JavaScript
> initialization takes place (from what I gather about IE, it's still a good
> idea to wait for dom:loaded, rather than simply putting the code at the
> bottom of the page), part of the process would be to a) fade out the dialog
> if showing and b) remove the onclick handler for any elements. This is
> tricky, because the initialization code often adds onclick event handlers.
> Perhaps the handlers can stay, but will be inactive because the page has
> loaded.
> Anyway, this is how I think we should proceed.
> I think this would keep compatibility with existing applications.
> The cost would be:
> - Slightly uglier HTML output (use of the "javascript:" psuedo-scheme)
> - Possibly slower render of page, as the browser waits for JavaScript to load
> - Increment increase in size of tapestry.js
> The advantage is less confusion on the client side and server side between
> normal requests and Ajax partial render requests. The user can't "outrace"
> the application anymore.
> I'd like to see what people think of this plan and collect any comments or
> observations I've missed.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.