Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
BTW, can't race conditions happen in the following case: A client without Javascript clicks on ActionLink before the page finishes loading. ? This does not seem like it can be handled with the help of Javascript. On Sun, Apr 12, 2009 at 8:43 PM, Sergey Didenko sergey.dide...@gmail.com wrote: Does it race when render request uses an object from HttpSession and concurrent action request changes that object? If so, can't it be handled on server? I'm worring that the current client-based approach is going to be overcomplicated. On Sun, Apr 12, 2009 at 8:19 PM, Sergey Didenko sergey.dide...@gmail.com wrote: Sorry if I ask a silly question, i'm a newbie to Tapestry. You mention there were race conditions on slow connections. How were they possible? If a page is rendering then it has already processed its handlers. So when a browser gets a half of the page, all the related handlers already finished their work, right? So what thing races with what? Regards, Sergey. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
By the time any markup is sent to the browser, the page will be finished rendering. Tapestry renders to a DOM then streams the DOM. Persistent fields will already be in the session, ready to be pulled out against a new page instance. On Mon, Apr 13, 2009 at 12:39 PM, Sergey Didenko sergey.dide...@gmail.com wrote: BTW, can't race conditions happen in the following case: A client without Javascript clicks on ActionLink before the page finishes loading. ? This does not seem like it can be handled with the help of Javascript. On Sun, Apr 12, 2009 at 8:43 PM, Sergey Didenko sergey.dide...@gmail.com wrote: Does it race when render request uses an object from HttpSession and concurrent action request changes that object? If so, can't it be handled on server? I'm worring that the current client-based approach is going to be overcomplicated. On Sun, Apr 12, 2009 at 8:19 PM, Sergey Didenko sergey.dide...@gmail.com wrote: Sorry if I ask a silly question, i'm a newbie to Tapestry. You mention there were race conditions on slow connections. How were they possible? If a page is rendering then it has already processed its handlers. So when a browser gets a half of the page, all the related handlers already finished their work, right? So what thing races with what? Regards, Sergey. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator of Apache Tapestry Director of Open Source Technology at Formos - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Sorry if I ask a silly question, i'm a newbie to Tapestry. You mention there were race conditions on slow connections. How were they possible? If a page is rendering then it has already processed its handlers. So when a browser gets a half of the page, all the related handlers already finished their work, right? So what thing races with what? Regards, Sergey. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Does it race when render request uses an object from HttpSession and concurrent action request changes that object? If so, can't it be handled on server? I'm worring that the current client-based approach is going to be overcomplicated. On Sun, Apr 12, 2009 at 8:19 PM, Sergey Didenko sergey.dide...@gmail.com wrote: Sorry if I ask a silly question, i'm a newbie to Tapestry. You mention there were race conditions on slow connections. How were they possible? If a page is rendering then it has already processed its handlers. So when a browser gets a half of the page, all the related handlers already finished their work, right? So what thing races with what? Regards, Sergey. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Hello, Further, on a page that loads slowly (one that has a large number of external scripts, is accessed 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. For this problem, doesn't the solution is server side ? I mean, if the (non-XHR) request return a Block, it's an error in T5, and all in all, there is no gracefull degradation. The server code should always distinguish between XHR events and normal requests, and return accordingly. Or perhaps it's a case of leaky abstraction : event handlers for normal requests and for XHR one's might be actually different beasts (onXhrAction / onAction ). I remember that there was several threads on that subject, especially this one : http://markmail.org/thread/ho3nla6eciyupcah Francois - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Great ideas and great suggestions. Personally I see two problems. Many requirements documents (typically those for government related projects) require sites to be fully functional with javascript disabled. The proposal does not seem to address that at this moment. Ideally we should be able to detect whether the browser has javascript enabled and produce different content (not sure how this can be efficiently handled though). Any attempts to produce html which does not need javascript and tweaking on-load creates too much flicker (or at least, that was the case in my pages). The other problem that I had with tapestry (more precisely, that my users complained about) is the ability too click before the page is fully ready. The easy solution for this would be a loading overlay which is disabled as the very last javascript which is executed. This can almost be done at this moment, except that I know of no way to force a piece of javascript to be executed after tapestry's internal handling. This approach itself has some problems combined with the javascript disabled browsers of course. All in all, I *assume* a lot can be gained from better caching and/or javascript combining (as partly done in 5.1 and partly planned). Looking at GWT pages for example they seem incredibly fast even with quite a lot of javascript. It may also be useful to investigate how images can be combined for faster loading (as GWT is also planning to do). Just my 2c. Joachim Howard Lewis Ship wrote: 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
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
On Sat, Feb 28, 2009 at 3:34 AM, farm...@linagora.com wrote: Hello, Further, on a page that loads slowly (one that has a large number of external scripts, is accessed 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. For this problem, doesn't the solution is server side ? I mean, if the (non-XHR) request return a Block, it's an error in T5, and all in all, there is no gracefull degradation. The server code should always distinguish between XHR events and normal requests, and return accordingly. Technically, that can be determined via the Request.isXHR() method. However, by then the horse has left the barn; in the race scenario, the user has clicked the link and initiated a full-page render even though the application developer had intended a partial render. The goal of the changes I'm outlining is to remove this race condition. Or perhaps it's a case of leaky abstraction : event handlers for normal requests and for XHR one's might be actually different beasts (onXhrAction / onAction ). I remember that there was several threads on that subject, especially this one : http://markmail.org/thread/ho3nla6eciyupcah Francois - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
I do like the fact that Javascript will move back into the head with this solution. It's pretty much 'the way of internet'. Everyone knows how to use it and almost all Javascript examples show it that way. Moving the Javascript-includes to the bottom made some things more difficult; you cannot quickly mockup a page using inline onclick-attributes for example, since the libraries you depend on may not have been loaded yet. I think it was an optimization step that was forced onto the user and impacted the way (s)he worked. I had to put in quite some effort to get pages working in Tapestry again that were sent to me by web-designers. That is, until it was possible to make the location of the Javascript configurable again. I'm not very happy with any popups or loading-messages being forced upon me though. There are still plenty of non-AJAX applications that work great without the entire page needing to be loaded, especially if you setup your pages to work without Javascript. Also, when the javascript-includes are inside the head, so can be the Javascript initialization code. This means you can execute the initialization code directly after the _DOM_ was loaded. When the scripts are at the bottom you have to wait until the _page_ (including all resources) is loaded because you depend on the javascript libraries being available. When using the dom-loaded event instead of the page-loaded event, it becomes much harder for a user to out-race Tapestry. On a slow connection, the hold-up is usually in resources, since only a couple of connections are made at once by the browser. The DOM is usually loaded pretty quickly and the other resources have to fight for a connection. I must admit I currently use hardly any AJAX, mostly because it is very hard to do in Tapestry. This is one area where Wicket is way ahead of Tapestry 5: you get back the full state of the page when a component makes a callback from the client to the server and from the handler you simply return all components that require updating. Wickets handles the stuff for you on the client. If you open a modal dialog for example, you can tell it to send callback when the dialog is opened, or moved, or closed etc. That way you can program pretty much all of the behavior using Java on the server. In Tapestry things are much more complex with Zones and lots of custom Javascript. I think we can learn some things here from Wicket. regards, Onno
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
So you think there's a difference between having the handler for the document dom:loaded event at the bottom of the page vs. the top? On Sat, Feb 28, 2009 at 7:25 AM, Onno Scheffers o...@piraya.nl wrote: I do like the fact that Javascript will move back into the head with this solution. It's pretty much 'the way of internet'. Everyone knows how to use it and almost all Javascript examples show it that way. Moving the Javascript-includes to the bottom made some things more difficult; you cannot quickly mockup a page using inline onclick-attributes for example, since the libraries you depend on may not have been loaded yet. I think it was an optimization step that was forced onto the user and impacted the way (s)he worked. I had to put in quite some effort to get pages working in Tapestry again that were sent to me by web-designers. That is, until it was possible to make the location of the Javascript configurable again. I'm not very happy with any popups or loading-messages being forced upon me though. There are still plenty of non-AJAX applications that work great without the entire page needing to be loaded, especially if you setup your pages to work without Javascript. Also, when the javascript-includes are inside the head, so can be the Javascript initialization code. This means you can execute the initialization code directly after the _DOM_ was loaded. When the scripts are at the bottom you have to wait until the _page_ (including all resources) is loaded because you depend on the javascript libraries being available. When using the dom-loaded event instead of the page-loaded event, it becomes much harder for a user to out-race Tapestry. On a slow connection, the hold-up is usually in resources, since only a couple of connections are made at once by the browser. The DOM is usually loaded pretty quickly and the other resources have to fight for a connection. I must admit I currently use hardly any AJAX, mostly because it is very hard to do in Tapestry. This is one area where Wicket is way ahead of Tapestry 5: you get back the full state of the page when a component makes a callback from the client to the server and from the handler you simply return all components that require updating. Wickets handles the stuff for you on the client. If you open a modal dialog for example, you can tell it to send callback when the dialog is opened, or moved, or closed etc. That way you can program pretty much all of the behavior using Java on the server. In Tapestry things are much more complex with Zones and lots of custom Javascript. I think we can learn some things here from Wicket. regards, Onno -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
I must admit that I haven't played around and tested it myself. It's mostly theory: Everything in the head is loaded and/or executed before the page continues loading. Therefore any Javascript-block in the head is executed immediately. In the case of prototype that means the event is bound immediately and theoretically it can be called earlier since the libraries are already loaded as well. When the Javascript is at the bottom, the different script tags are handled in the order they appear (since they may depend on one another). So reading of the page may stop while waiting for the resources to come in. Large parts of the page may already be displayed then, allowing the user to click on links and buttons. So even though the event that was being acted upon was dom:loaded, it pretty much acted as a page-loaded event since the final resources to be loaded are the javascript-includes at the bottom of the page. Initialization code cannot be run without those resources being loaded and this happens while the browser is already showing the content it has. regards, Onno On Sat, Feb 28, 2009 at 5:21 PM, Howard Lewis Ship hls...@gmail.com wrote: So you think there's a difference between having the handler for the document dom:loaded event at the bottom of the page vs. the top? On Sat, Feb 28, 2009 at 7:25 AM, Onno Scheffers o...@piraya.nl wrote: I do like the fact that Javascript will move back into the head with this solution. It's pretty much 'the way of internet'. Everyone knows how to use it and almost all Javascript examples show it that way. Moving the Javascript-includes to the bottom made some things more difficult; you cannot quickly mockup a page using inline onclick-attributes for example, since the libraries you depend on may not have been loaded yet. I think it was an optimization step that was forced onto the user and impacted the way (s)he worked. I had to put in quite some effort to get pages working in Tapestry again that were sent to me by web-designers. That is, until it was possible to make the location of the Javascript configurable again. I'm not very happy with any popups or loading-messages being forced upon me though. There are still plenty of non-AJAX applications that work great without the entire page needing to be loaded, especially if you setup your pages to work without Javascript. Also, when the javascript-includes are inside the head, so can be the Javascript initialization code. This means you can execute the initialization code directly after the _DOM_ was loaded. When the scripts are at the bottom you have to wait until the _page_ (including all resources) is loaded because you depend on the javascript libraries being available. When using the dom-loaded event instead of the page-loaded event, it becomes much harder for a user to out-race Tapestry. On a slow connection, the hold-up is usually in resources, since only a couple of connections are made at once by the browser. The DOM is usually loaded pretty quickly and the other resources have to fight for a connection. I must admit I currently use hardly any AJAX, mostly because it is very hard to do in Tapestry. This is one area where Wicket is way ahead of Tapestry 5: you get back the full state of the page when a component makes a callback from the client to the server and from the handler you simply return all components that require updating. Wickets handles the stuff for you on the client. If you open a modal dialog for example, you can tell it to send callback when the dialog is opened, or moved, or closed etc. That way you can program pretty much all of the behavior using Java on the server. In Tapestry things are much more complex with Zones and lots of custom Javascript. I think we can learn some things here from Wicket. regards, Onno -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Em Sat, 28 Feb 2009 09:20:50 -0300, Joachim Van der Auwera joac...@progs.be escreveu: Looking at GWT pages for example they seem incredibly fast even with quite a lot of javascript. GWT is a very different beast. It generates a single JavaScript file with the whole application code and loads it up front. Example: Gmail. This approach can't be used in a framework like Tapestry, AFAIK. -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor Consultor, desenvolvedor e instrutor em Java http://www.arsmachina.com.br/thiago - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Interesting; first I have to figure out how to accurately measure this stuff (any ideas?), then we'll see if it makes a difference where the page initialization logic actually goes. BTW I just checked in the first pass at these changes; it needs a couple of tweaks but I'm pretty happy about how it's coming out. On Sat, Feb 28, 2009 at 10:30 AM, Onno Scheffers o...@piraya.nl wrote: I must admit that I haven't played around and tested it myself. It's mostly theory: Everything in the head is loaded and/or executed before the page continues loading. Therefore any Javascript-block in the head is executed immediately. In the case of prototype that means the event is bound immediately and theoretically it can be called earlier since the libraries are already loaded as well. When the Javascript is at the bottom, the different script tags are handled in the order they appear (since they may depend on one another). So reading of the page may stop while waiting for the resources to come in. Large parts of the page may already be displayed then, allowing the user to click on links and buttons. So even though the event that was being acted upon was dom:loaded, it pretty much acted as a page-loaded event since the final resources to be loaded are the javascript-includes at the bottom of the page. Initialization code cannot be run without those resources being loaded and this happens while the browser is already showing the content it has. regards, Onno On Sat, Feb 28, 2009 at 5:21 PM, Howard Lewis Ship hls...@gmail.com wrote: So you think there's a difference between having the handler for the document dom:loaded event at the bottom of the page vs. the top? On Sat, Feb 28, 2009 at 7:25 AM, Onno Scheffers o...@piraya.nl wrote: I do like the fact that Javascript will move back into the head with this solution. It's pretty much 'the way of internet'. Everyone knows how to use it and almost all Javascript examples show it that way. Moving the Javascript-includes to the bottom made some things more difficult; you cannot quickly mockup a page using inline onclick-attributes for example, since the libraries you depend on may not have been loaded yet. I think it was an optimization step that was forced onto the user and impacted the way (s)he worked. I had to put in quite some effort to get pages working in Tapestry again that were sent to me by web-designers. That is, until it was possible to make the location of the Javascript configurable again. I'm not very happy with any popups or loading-messages being forced upon me though. There are still plenty of non-AJAX applications that work great without the entire page needing to be loaded, especially if you setup your pages to work without Javascript. Also, when the javascript-includes are inside the head, so can be the Javascript initialization code. This means you can execute the initialization code directly after the _DOM_ was loaded. When the scripts are at the bottom you have to wait until the _page_ (including all resources) is loaded because you depend on the javascript libraries being available. When using the dom-loaded event instead of the page-loaded event, it becomes much harder for a user to out-race Tapestry. On a slow connection, the hold-up is usually in resources, since only a couple of connections are made at once by the browser. The DOM is usually loaded pretty quickly and the other resources have to fight for a connection. I must admit I currently use hardly any AJAX, mostly because it is very hard to do in Tapestry. This is one area where Wicket is way ahead of Tapestry 5: you get back the full state of the page when a component makes a callback from the client to the server and from the handler you simply return all components that require updating. Wickets handles the stuff for you on the client. If you open a modal dialog for example, you can tell it to send callback when the dialog is opened, or moved, or closed etc. That way you can program pretty much all of the behavior using Java on the server. In Tapestry things are much more complex with Zones and lots of custom Javascript. I think we can learn some things here from Wicket. regards, Onno -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Em Fri, 27 Feb 2009 21:11:15 -0300, Howard Lewis Ship hls...@gmail.com escreveu: 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. That's nice, but don't forget about i18ning the wait until the page finishes loading message. ;) The cost would be: - Slightly uglier HTML output (use of the javascript: psuedo-scheme) Not really a problem, as only AJAXified links would be affected. - Increment increase in size of tapestry.js Why would it increase in size? By how much? 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. To me, this is more important than anything else. Howard, I'm no AJAX expert, but I think you're going in the right direction. ;) -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor http://www.arsmachina.com.br/thiago - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Interesting; first I have to figure out how to accurately measure this stuff (any ideas?), then we'll see if it makes a difference where the page initialization logic actually goes. Maybe slow down the stream for the Javascript-library response. Are they returned by the asset-service? maybe the response can be slowed down to a couple of seconds per library. Add a simple piece of javascript that shows an alert-box. First put everything in the head. You should see the alert-box before anything renders. Then put eveything at the bottom of the page. If I'm not mistaken, you should see part of the page before the alert-box is shown. it is not an accurate measurement, but you can see clearly how different browsers handle things. regards, Onno BTW I just checked in the first pass at these changes; it needs a couple of tweaks but I'm pretty happy about how it's coming out. On Sat, Feb 28, 2009 at 10:30 AM, Onno Scheffers o...@piraya.nl wrote: I must admit that I haven't played around and tested it myself. It's mostly theory: Everything in the head is loaded and/or executed before the page continues loading. Therefore any Javascript-block in the head is executed immediately. In the case of prototype that means the event is bound immediately and theoretically it can be called earlier since the libraries are already loaded as well. When the Javascript is at the bottom, the different script tags are handled in the order they appear (since they may depend on one another). So reading of the page may stop while waiting for the resources to come in. Large parts of the page may already be displayed then, allowing the user to click on links and buttons. So even though the event that was being acted upon was dom:loaded, it pretty much acted as a page-loaded event since the final resources to be loaded are the javascript-includes at the bottom of the page. Initialization code cannot be run without those resources being loaded and this happens while the browser is already showing the content it has. regards, Onno On Sat, Feb 28, 2009 at 5:21 PM, Howard Lewis Ship hls...@gmail.com wrote: So you think there's a difference between having the handler for the document dom:loaded event at the bottom of the page vs. the top? On Sat, Feb 28, 2009 at 7:25 AM, Onno Scheffers o...@piraya.nl wrote: I do like the fact that Javascript will move back into the head with this solution. It's pretty much 'the way of internet'. Everyone knows how to use it and almost all Javascript examples show it that way. Moving the Javascript-includes to the bottom made some things more difficult; you cannot quickly mockup a page using inline onclick-attributes for example, since the libraries you depend on may not have been loaded yet. I think it was an optimization step that was forced onto the user and impacted the way (s)he worked. I had to put in quite some effort to get pages working in Tapestry again that were sent to me by web-designers. That is, until it was possible to make the location of the Javascript configurable again. I'm not very happy with any popups or loading-messages being forced upon me though. There are still plenty of non-AJAX applications that work great without the entire page needing to be loaded, especially if you setup your pages to work without Javascript. Also, when the javascript-includes are inside the head, so can be the Javascript initialization code. This means you can execute the initialization code directly after the _DOM_ was loaded. When the scripts are at the bottom you have to wait until the _page_ (including all resources) is loaded because you depend on the javascript libraries being available. When using the dom-loaded event instead of the page-loaded event, it becomes much harder for a user to out-race Tapestry. On a slow connection, the hold-up is usually in resources, since only a couple of connections are made at once by the browser. The DOM is usually loaded pretty quickly and the other resources have to fight for a connection. I must admit I currently use hardly any AJAX, mostly because it is very hard to do in Tapestry. This is one area where Wicket is way ahead of Tapestry 5: you get back the full state of the page when a component makes a callback from the client to the server and from the handler you simply return all components that require updating. Wickets handles the stuff for you on the client. If you open a modal dialog for example, you can tell it to send callback when the dialog is opened, or moved, or closed etc. That way you can program pretty much all of the behavior using Java on the server. In Tapestry things are much more complex with Zones and lots of custom Javascript. I think we can learn some things here from Wicket.
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
I think some actual hard numbers would help with this. If an example page renders one way with js at the bottom, and another way with js at the top, these can be timed and compared. If real-world performance differences are at an acceptable minimum, then it's fine. But the fact that top is slower than bottom based on knowledge of how they render isn't enough, I think. Does anyone have a setup that could conveniently test page load/render times with these two configurations on an (otherwise) identical setup? Christian. On 27-Feb-09, at 19:11 , Howard Lewis Ship wrote: 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
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
On Sat, 28 Feb 2009 01:11:15 +0100, Howard Lewis Ship hls...@gmail.com wrote: 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. I didn't quite understand this part. If a user clicks the link before its onclick handler has been added, wouldn't that result in the same behaviour as having javascript disabled? - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
Initialy, the onclick handler would be supplied as: a href=mpage.mycomponent onclick=javascript:Tapestry.waitForPageLoad();update zone/a Thus, if you click it while the page is still loading, the waitForPageLoad() function will be invoked, which can raise the warning dialog. Once the page is fully loaded, the waitForPageLoad() handler is removed or deactivated, and additional onclick event handlers can be added via Prototype's Event.observe() function. The diffrerence between this and Tapestry 5.1.0.0 is that there's no inline onclick event handler; clicking the link while the scripts are loading results in a non-Ajax component event request (as opposed to an Ajax component event request via XmlHttpRequest). On Fri, Feb 27, 2009 at 4:41 PM, Martin Strand do.not.eat.yellow.s...@gmail.com wrote: On Sat, 28 Feb 2009 01:11:15 +0100, Howard Lewis Ship hls...@gmail.com wrote: 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. I didn't quite understand this part. If a user clicks the link before its onclick handler has been added, wouldn't that result in the same behaviour as having javascript disabled? - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator Apache Tapestry and Apache HiveMind - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: [DISCUSS] JavaScript, Degradation, Page Load, Script Placement
On 27-Feb-09, at 19:41 , Martin Strand wrote: On Sat, 28 Feb 2009 01:11:15 +0100, Howard Lewis Ship hls...@gmail.com wrote: 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. I didn't quite understand this part. If a user clicks the link before its onclick handler has been added, wouldn't that result in the same behaviour as having javascript disabled? It would have, but with that solution, url's just had http://www.blah.com/context/page/# as the url to be clicked, which means that non-javascript clients, treating it as the same as if javascript was disabled, would try to access the in-page anchor , which clearly doesn't exist. It would amount to a page refresh, and on some browsers not even that, since the browser would cache the page since you're not going anywhere. So for non-js or js-disabled clients, you need a real URL. christian. Christian Edward Gruber e-mail: christianedwardgru...@gmail.com weblog: http://www.geekinasuit.com/ - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org