I have a performance issue with my JSF page and can not find an solution. I'm using JSF 2.0.
I click on an element to render another element :
<f:ajax event="click" listener="#{row.select}" render=":dataWrapper"/>
After click the data panel will be rendered. My problem is when I click on the element again. The data panel will be rendered too, but it will takes more time. If I click the third time the rendering needs again more time. And so on ...
What can be the reason for this?
I checked the request with the Firefox debugger and everything looks fine, except the reponse time.
The response time will grow up every request.
Related
I have a list element detail form opening inside a p:dialog. This p:dialog in turn shows another list. From this list, I can open any of its element's details inside a nested p:dialog.
The problem is: every time I open a dialog, a new set of ids for the elements in the nested dialog is generated, with the same value.
What I end up with in my DOM when I try to select a particular id from the nested dialog, such as $('#manageIssue\\:newEventComment');, is an array of elements with the same id.
I have determined there is one copy per each time I open a dialog, plus another one which is there from the beginning.
The nested dialog DOM nodes are not being destroyed when the nested dialog is closed, and a fresh set with overlapping ids is being generated every time a dialog is opened.
This question is related to primefaces update attribute not working on modal dialog opened from modal dialog.
(I solved the original problem by removing the prependId attribute from the form, but this one remained.)
Because this problem is a little difficult to reproduce, I have built a MCVE. All the stuff (backing beans, views, pom.xml, etc.) adds up to ~500 lines of code, so I have shared it on a github repo: https://github.com/elcodedocle/testt
The question here boils down to:
How can I make this MCVE work (i.e. add events with comments to an issue from a list of issues of a commission from a list of commissions), without this line:
https://github.com/elcodedocle/testt/blob/fbfeb7fca474c66c202c92e469ca185c6bf569c2/src/main/webapp/views/widgets/issue_detail_edit.xhtml#L21
?
This problem is caused by nested <p:dialog>.
<p:dialog id="commissionDetail">
...
<p:dialog id="issueDetail">
...
</p:dialog>
</p:dialog>
This is not allowed. The technical reason is, the HTML DOM element representing the dialog is by JavaScript relocated to the very end of <body> in order to ensure best cross browser compatibility as to calculating the z-index and offset. Then, when you ajax-update the dialog, the existing dialog couldn't be found in its original parent element in the DOM, so simply a new one is added to DOM (which then get relocated to end of body again, etc).
You really need to restructure your templates so you ultimately end up like
<p:dialog id="commissionDetail">
...
</p:dialog>
<p:dialog id="issueDetail">
...
</p:dialog>
If you do JSF AJAX calls and change the component tree while rerendering (or between ajax calls), you'll get exceptions from Mojarra. As I understand it, it's difficult to recreate the component tree partially when the new tree is different as the one stored in the ViewState (or the actual JSF class). That's "ok". I'm thinking about using the rendered attribute and not rendering the component.
My question: How does the rendered attribute work? Does the component get restored and is the component tree, that JSF creates during restore phase, safe? We have a very dynamic XHTML page and not rendering object's instead of disabling them with css classes would really up the speed of the page.
I tried it and it works as expected. So JSF only assumes that the component is there even if it doesn't render anything.
Please consider that the view state does get restored and it's still a performance hit (but a smaller one as nothing get's sent over the wire and the output string/html doesn't need to be rendered).
Referencing this question because the problem is identical to mine, but I don't think the solution is usable in my situation.
continuation of pressing button twice
I have a workflow with a series of forms that need to be filled out and submitted, and I would like to display a modal overlay after the user clicks the "next" button. In order to show this overlay, I need to make the command button use ajax. This leads to the undesired behavior as described in the linked issue.
The solution for the linked issue seemed to be "don't use Ajax for navigation", but I think in my case I may have to in order to show this waiting dialogue. Is there any other way to guarantee that the view state on the following page will be updated correctly, so that when I continue navigating I do not need to hit the button twice?
I am using Primefaces 3.3.1.
<p:commandButton id="nextCommand" value="Next"
action="#{backingBean.processInputAndDetermineOutcome}"
onclick="waiter.show();" oncomplete="waiter.hide();">
<f:param name="validate" value="true" />
</p:commandButton>
The "validate" param is a flag I am using in a custom BeanValidator so that my "Back" button can submit the form and update the model without processing any of the valdations. I don't think that should have any impact on this question, but I thought I should mention what other pieces are involved in this commandButton.
Your best bet is to navigate with a redirect.
public String processInputAndDetermineOutcome() {
// ...
return outcome + "?faces-redirect=true";
}
Otherwise, for sure if you're actually observing the problem in IE browser only and not in other, more sane, browsers, then you may want to try the PrimeFaces-specific JavaScript fix as proposed here: JSF Language switcher and ajax update.
Or, if you're actually observing the problem in <f:ajax> and not in <p:ajax>, then try the JSF-specific JavaScript fix as proposed here: h:commandButton/h:commandLink does not work on first click, works only on second click.
My project is using Wicket's AjaxFormValidatingBehavior to auto-save form content to Session on sort of a multi-tab form with a tree menu (there is no save button on individual tabs, though there is a "Save" button that actually submits the form, runs the validations and saves contents to database). I am facing few issues:
Since the behavior is added to all form components' onChange event, there is a server-trip every time user moves from one field to another. I know that a throttle duration can be specified to prevent this, but its not possible to set in my case as my forms are of different lengths/complexity, many components dynamically generated (including the tree menu). But is there a more elegant solution to auto-save form content (that doesn't have a submit button) rather than this annoying solution.
Another issue I am facing is that post onChange event, on Firefox the component loses its focus after the "server trip" ends. While on IE7 it works fine.
For the first question I think you need to add a pipelining facility, on your components' onchange call a javascript function of your which calls your webapp. You can include a feature similar to the one provided with the throttle duration but page-wide (delay each calls and only trigger the last if it is older than x milliseconds for example).
For the second one, I think you have to use the AjaxRequestTarget#focusComponent in your behaviors, or handle this thing in your "wrapper" as described in the first answer.
If we have a page which executes Javascript upon loading, and this Javascript inserts new elements via AJAX, will this delay the time it takes for the DOM to be considered loaded?
Some of our UI only functions after the DOM is loaded (using jQuery's "ready" function), and we thought inserting page elements asynchronously via AJAX would load the DOM faster, increase perceived responsiveness, and allow users to interact with the page sooner. If this is right, we are doing something wrong.
Any thoughts?
Thanks!
If I understand what you're trying to do, you want to load the page and then load the content asynchronously. If you want to do this to improve perceived load speeds, run your ajax code from your $(function(){}); call, not before. This fires when the DOM has loaded, which means all the rest of your page (except what you're trying to load asynchronously) has loaded.
The effect the user will perceive is that the whole page except the content loads (I assume you'll have some sort of spinning image or something where your content is going to be loaded), then you make the call, then you remove the loading icon and insert your content.