Primefaces Dialog Framework Perfomance issue - performance

we are building a Java EE 7 website and having a problem with performance in some situations.
We are using the following components and technologies:
Java 1.7
JSF 2.2
EclipseLink 2.5.1
PrimeFaces 4.0
Glassfish Server 4.0
Advantage Database Server 10.10
So, what is our problem exactly? In our main page (round about 2000 DOM elements, mainly JSF and Primefaces elements) we are using the actionListener-Tag of a p:commandButton to call a Java method in a backing bean which opens a dialog (JaNeinDialog) of the primefaces dialog framework.
Since our JaNeinDialog is quite simple, we would expect it to be opened in the browser (firefox 27.0.1) almost immediately. But in fact, it takes 1-2 seconds unitl it is visible.
Amazingly, we have found out, that this waiting time is directly dependent from the original place from where it has been called: As soon as this commandLink is located within a very simple xhtml-page, we see what we had expected: The dialog opens with almost no delay.
So the question is: Why depends the loading time of the same dialog from the complexity of the page from where it has been called?
p:CommandButton which calls a Java method in order to open the JaNeinDialog:
<p:commandLink ajax="true" process="#this"
actionListener="#{patientController.starteMitarbeiterSucheDialog()}">
<p:graphicImage value="/resources/img/png/find_1.png" width="18"
height="21" title="Suche nach Mitarbeiter" />
<p:ajax event="dialogReturn" update="editPflegeDatenPanel"
listener="#{patientController.setPatientMitarbeiter}" />
</p:commandLink>
JaNeinDialog.xhtml:
<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title><h:outputText
value="#{stringKonstanten.jaNeinDialogTitel}"/></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
<h:outputStylesheet library="css" name="jortho.css" />
</h:head>
<h:body>
<h:form>
<center>
<p:panelGrid id="JaNeinDialogPanel" cellspacing="5">
<p:row>
<p:column colspan="2">
<center>
<h:outputText value="#{jaNeinDialogController.dialogText}" />
</center>
</p:column>
</p:row>
<p:row>
<p:column colspan="2">
<center>
<h:outputText value="Aktion ausführen?" />
<BR />
<BR />
</center>
</p:column>
</p:row>
<p:row>
<p:column>
<center>
<p:commandButton id="positiveButton"
actionListener="#{jaNeinDialogController.entscheidungWeiterleiten(true)}"
value="#{stringKonstanten.ja}" icon="ui-icon-check" />
<p:commandButton id="negativeButton"
actionListener="#{jaNeinDialogController.entscheidungWeiterleiten(false)}"
value="#{stringKonstanten.nein}" icon="ui-icon-close" />
</center>
</p:column>
</p:row>
</p:panelGrid>
</center>
</h:form>
</h:body>
</ui:composition>
The used JSF version is the standard Mojarra 2.2.0 implementation which comes along with the Glassfish 4 server.
We've also checked, that there are no scripts being loaded in the body section. Only 2 scripts are
loaded in the head section.
Trying the suggestion with flushing, we have followed BalusCs instuction on
How to flush buffer early in JSF 2.0? in
order to reduce the waiting time for the response. Indeed, this waiting time has decreased by
round about 150 ms, but came along with some strange side-effects. Since BalusC does not recommend
to use this approach, we reverted this changes.
Using the Firefox-plugin YSlow, we have measured the response time until the dialog shows up. The waiting time for the first element (main.xhtml)
takes more than 800 ms waiting time. But the size of this first element is only
987 B. So, how can we find out, what exactly happens in the waiting time of the first element?
We have learned from https://blog.oio.de/2013/05/06/jsf-performance-tuning/ that changing the
JSF implementation from Mojarra to MyFaces will improve the performance significantly and we will
try to change it now at our Glassfish web server.
We would greatly appreciate any help. Thanks a lot in advance!
UPDATE:
Like suggested from lu4242 (thanks a lot for your assistance!), we tried to change the JSF implementation from Mojarra 2.2.0 to MyFaces.
Unfortunately, we were not able to deploy our application after we did this. The whole procedure is described here:
Java EE 7 Application not deploying on Glassfish 4 Sever after switching from Mojarra to MyFaces
After that, we learned from http://blog.oio.de/2013/05/16/jsf-performance-mojarra-improves-dramatically-with-latest-release/
that since Mojarra Version 2.1.22 the vast performance loss for sites with a high amount of DOM elements has been fixed.
Therefore we updated Mojarra from version 2.2.0 to 2.2.6, but there is still no improvement of our waiting time. Regardless of what we are doing on our main page, we still have a waiting time of round about 700ms.
YSlow shows, that the size of data transferred from server to browser is minimal (less than 10KB). But the main page is keeping the server busy for a much too long time.
So, we would appreciate any more tipps on this topic.
Thanks a lot in advance.

Related

Richfaces 4 select only gets rendered correctly after a site refresh

I don't know if I'm doing something wrong or if it might be a bug or something.
My setup contains IntelliJ IDEA 12, JBoss AS 7.2.0.Final, Richfaces 4.3.4 within a war-File within an ear-Project (no Maven).
I have this index-page:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<rich:notifyMessage stayTime="3500" showShadow="true" showCloseButton="true" />
<f:view>
<h:head> <title> title </title> </h:head>
<h:body>
<!-- some more divs for page-design, but commented out at the moment -->
<div id="page">
<div id="index_workspace" style="width:1000px;margin:auto;">
<h:panelGrid columns="2" id="index_workspace_table">
<rich:panel id="index_workspace_navi_left" style="width:180px;min-height:600px;max-height:600px;">
<ui:include src="general/navi_left.xhtml"/>
</rich:panel>
<rich:panel id="index_workspace_content" style="width:550px; min-height:600px; max-height:600px;" rendered="#{not empty naviBean.content}">
<a4j:outputPanel id="index_workspace_content_ajax" ajaxRendered="true">
<ui:include src="#{naviBean.content}" id="current_site" />
</a4j:outputPanel>
</rich:panel>
</h:panelGrid>
</div>
<!-- some more divs for page-design, but commented out at the moment -->
</div>
</h:body>
</f:view>
</ui:composition>
Within the section I load the pages with forms and all the other cool stuff RF brings. But I have a rendering problem with this part of a loaded page:
<rich:select id="someID_1" rendered="true" immediate="true" required="true" enableManualInput="true" defaultLabel="someLabel">
<a4j:ajax render="true">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</a4j:ajax>
</rich:select>
And here my problem is located:
This drop-down list only gets rendered on a page reload, e.g. F5 or CTRL-R action.
Also I could observe that if I set this element on some Kind of a "start page" (initially loaded on the index.xhtml) it gets rendered very well. In this case every other page containing this kind of element renders it correctly also.
I tried
updating JSF from 2.1 to 2.2.1 - that only brought up more problems - so I rolled it back.
The "standard" h:selectOneMenu behaves the same.
additional options within rich:select (e.g.: rendered, immediate, required, ...)
different ajax commands within the navigation (server, client, ajax, on different levels)
googling around since days - found no useable hint
I would appreciate every hint that guides me into the right direction as I feel confident, that I make some mistake I can't figure out...
Additionally my navigation looks like this (in another div on the index.xhtml):
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<h:form id="navi_left">
<rich:panel>
<rich:panelMenu itemMode="ajax" groupMode="ajax" itemChangeListener="#{naviBean.updateContent}" >
<rich:panelMenuGroup itemLeftIcon="disc" label="Erfassung" name="#{naviBean.content}">
<rich:panelMenuItem label="someLabel_navi" name="path/to/page-not-getting-rendered-well.xhtml"/>
</rich:panelMenuGroup>
</rich:panel>
</h:form>
</ui:component>
Hope this helps helping me.
<a4j:ajax render="true">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</a4j:ajax>
The above construct is not legal(as you've already seen yourself). The render attribute in there is not used for what you'd expect: to conditionally render the component; Rather, it's supposed to contain a list of on-page components to update via ajax.
To achieve the output I presume you're trying to get, you should use the following instead:
<a4j:region>
<rich:select id="someID_1" rendered="true" immediate="true" required="true" enableManualInput="true" defaultLabel="someLabel">
<f:selectItems id="selectlist" value="#{BackingBean.SelectableItem-ListGetter}"/>
</rich:select>
<a4j:region>
I think I found the problem. As my navigation and my desired site with the not correctly rendered component lie nested in <div>s on the third participating site - my index.xhtml - it seems to be impossible to let a jsf-component be rendered without having all (i.e. the navigation and the desired) sites processed on the server. So the following code-snippets work for my situation:
index.xhtml snippet:
<rich:panel id="index_workspace_content" style="width:550px; min-height:600px; max-height:600px;" rendered="#{not empty naviBean.content}">
<ui:include src="#{naviBean.content}" id="current_site" />
</rich:panel>
navi_left.xhtml snippet:
<h:form id="navi_left">
<rich:panel>
<rich:panelMenu itemMode="server" groupMode="client" itemChangeListener="#{naviBean.updateContent}">
<rich:panelMenuGroup label="someLabel" name="#{naviBean.content}">
<rich:panelMenuItem label="anotherLabel" name="path/to/page-being-rendered-correctly.xhtml"/>
</rich:panelMenuGroup>
...
</h:form>
component snippet in the desired.xhtml:
<rich:select id="someId" rendered="true" immediate="true" required="true" enableManualInput="true">
<f:selectItems var="#{backingBean.selectableItemList}" id="selectlist" value="#{backingBean.predefinedItem}"/>
</rich:select>
So what I have changed is the itemMode to "server", both of the others (ajax and client) will not work!
Setting the groupMode to "client" does not affect the renderprocess of desired.xhtml as it only describes the way the rich:panelMenu behaves.
What makes me feel a bit confused is, that the URL now gets extended with a "/index.xhtml". Before the change it was always just the url:port/context (e.g. localhost:8080/app ).
So it works now, but maybe it's not really what I wanted. I'll observe and report future facts concerning this itemMode-option here.

JSF render data table content from managed-bean?

I'm using Richfaces to develop some web pages, with a datatable I try to display some data information from remote server. But its quite slow to load all data in one time, so I use a cache to store data, Firstly my cache is empty and data table is empty.
The ideal goal is loading one row from server(let say 1mins for each row) and store into my cache, then append into data table's end, my question is how can I render the content of data table from managedbean once I retrieve some new data into cache?
I also use a timer to update the cache values from server during a fixed period (1hour), that means later, new data could be added into cache, and old data could be removed from cache, that all depend on server's latest data. same question when I get a fresh cache and need rerender data table content according to cache values.
Thanks,
The most easy way to do this is rerendering your table. There are two approaches to do this using RichFaces library:
Client Side
The a4j:poll component defines a way to periodically poll a server in order to trigger state changes, or update parts of your page. It uses a timer to trigger each N milliseconds.
You can use it to check your cache data on your server and then rerender your table.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:form>
<a4j:poll id="poll" interval="2000" enabled="#{pollBean.pollEnabled}" render="poll,grid" />
</h:form>
<h:form>
<h:panelGrid columns="2" width="80%" id="grid">
<h:panelGrid columns="1">
<h:outputText value="Polling Inactive" rendered="#{not pollBean.pollEnabled}"></h:outputText>
<h:outputText value="Polling Active" rendered="#{pollBean.pollEnabled}"></h:outputText>
<a4j:commandButton style="width:120px" id="control" value="#{pollBean.pollEnabled?'Stop':'Start'} Polling"
render="poll, grid">
<a4j:param name="polling" value="#{!pollBean.pollEnabled}" assignTo="#{pollBean.pollEnabled}" />
</a4j:commandButton>
</h:panelGrid>
<h:outputText id="serverDate" style="font-size:16px" value="Server Date: #{pollBean.date}" />
</h:panelGrid>
</h:form>
</ui:composition>
More information on RichFaces a4j:poll.
Server Side
The a4j:push works as a consumer/producer architecture, which uses no timer, instead it uses a message that will instruct the client to re-render part of the page.
Using this component you will be able to have an impact on the client side (rerender HTML) from the java methods in your ManagedBean. Maybe the problem here will be to communicate your current cache architecture with your JSF Managed Bean.
More information on RichFaces a4j:push.
Regards,

Display a list of images in a table format in JSF

This is probably a really simple JSF question, but I can't seem to find the simple answer.
I have a List of images, and I want to display them in a table of images. Each image is displayed with its filename. I'm using a ui:repeat tag as shown below. I don't get 5 columns as requested, however, only 1.
<h:panelGrid id="resourcePanel" columns="5" rules="all">
<ui:repeat var="res" value="#{resourceUpload.resources}">
<h:panelGrid columns="1" rules="none">
<h:graphicImage
value="/image/resource?id=#{res.idAsString}"
style="width:100px;" />
<h:outputText value="#{res.name}" />
</h:panelGrid>
</ui:repeat>
</h:panelGrid>
The output is fully as expected and specified. The <ui:repeat> is a render time tag, not a view build time tag like <c:forEach>. After building the view, <h:panelGrid> ends up with 1 child component (the <ui:repeat> itself), not with n nested <h:panelGrid> components like as you would get with <c:forEach>.
<html ... xmlns:c="http://java.sun.com/jsp/jstl/core">
...
<h:panelGrid id="resourcePanel" columns="5" rules="all">
<c:forEach var="res" items="#{resourceUpload.resources}">
<h:panelGrid columns="1" rules="none">
<h:graphicImage
value="/image/resource?id=#{res.idAsString}"
style="width:100px;" />
<h:outputText value="#{res.name}" />
</h:panelGrid>
</c:forEach>
</h:panelGrid>
(this has in the Mojarra versions older than 2.1.18 however an implication on #{resourceUpload}: it can't be a view scoped bean, it must be request scoped due to a chicken-egg issue in view state saving/restoring; you'd need to upgrade to Mojarra 2.1.18)
Your nested <h:panelGrid> makes by the way no utter sense. I'd have used <h:panelGroup> here.
See also:
JSTL in JSF2 Facelets... makes sense? - to understand "view build time" vs "view render time" better
create table columns dynamically in JSF - another similar question
Why do you use another <h:panelGrid> inside the <ui:repeat>? You can just use a div like this.
Instead of
<h:panelGrid columns="1" rules="none">
use
<div style="display:inline-block;">
Edit:
I don't think that you can do it with <ui:repeat>. Use <c:forEach> instead.
First you should import the namespace
xmlns:c="http://java.sun.com/jstl/core"
Now replace the <ui:repeat> with <c:forEach> like this.
<c:forEach items="#{accountMastList.resultList}" var="res">

Although some validators in JSF are functioning well, some error messages or possibly some warnings appear on the console

In my web application in JSF, some validators such as a length validator <f:validateLength></f:validateLength>, a regular expression validator <f:validateRegex></f:validateRegex> and some other issue some error possibly a warning even if they are functioning well with no problem at all, when the JSF page is loaded.
The JSF ManagedBean is unnecessary here and the submit button presented in the following code has nothing to do with, since Ajax is fired on the valueChange event of the text field given.
Following is the simple JSF page code.
<?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Demo</title>
</h:head>
<h:body>
<h:form>
<center><br/><br/><br/>
<h:inputText id="txtDemo" required="true" requiredMessage="Mandatory."
validatorMessage="The field should contain al least 10 digits">
<f:validateLength id="lenValidator" for="txtDemo" maximum="10"
minimum="2"/>
<f:validateRegex pattern="[0-9]*" for="txtDemo" id="txtPattern"/>
<f:ajax id="txtAjax" event="valueChange" execute="txtDemo msg"
render="txtDemo msg"/>
</h:inputText><br/>
<h:message id="msg" for="txtDemo" showDetail="true" style="color:red"/>
<br/>
<h:commandButton id="btnSubmit" value="Submit"/>
</center>
</h:form>
</h:body>
In the above code, although the validators <f:validateLength></f:validateLength> and <f:validateRegex></f:validateRegex> are functioning well, the length validator does not allow less than 2 and greater than 10 characters and the regular expression validator ensures that the field should contain only digits, red colored messages appear on the console, when this JSF page is load. The messages displayed are as follows.
SEVERE: /Restricted/TempTags.xhtml #12,93 id="lenValidator" Unhandled by MetaTagHandler for type javax.faces.validator.LengthValidator
SEVERE: /Restricted/TempTags.xhtml #13,82 id="txtPattern" Unhandled by MetaTagHandler for type javax.faces.validator.RegexValidator
Why are these messages displayed, event if they are functioning well with no problem?
It's just telling that the id attribute of those tags is not been handled. Indeed, those tags do not support an id attribute. Remove it.
<f:validateLength for="txtDemo" maximum="10" minimum="2"/>
<f:validateRegex for="txtDemo" pattern="[0-9]*" />
The for attribute is by the way unnecessary in this construct. You could also safely remove it. The for attribute applies only when targeting validators on inputs inside composite components.
See also:
JSF 2.1 tag documentation
<f:validateLength> tag documentation
<f:validataRegex> tag documentation
Unrelated to the concrete problem, the <center> element is deprecated since HTML 4.01 in 1998. Remove it as well. Use CSS margin: 0 auto on the containing block element with a fixed width instead.

JSF 2.0 and JSTL use of c:set tag to store some temporary data

I'm developing a web application with JSF 2.0 (mojarra) + primefaces. In the past I successfully used the [c:set] tag of jstl library to store some temporary data or output form other tags.
In my current case I want to use that again but it doesn't work properly and I have no idea why. In the follow example it works but particularly. Why does the case 2 not work properly?
<h:form id="userAdministration">
<p:messages id="messages" showDetail="true" />
<p:dataTable id="userTable" selectionMode="single" var="user" value="#{users}">
<p:column>
<f:facet name="header">
<h:outputText value="#{message.user_table_header_id_column}" />
</f:facet>
<h:outputText value="#{user.id}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{message.global_table_header_action_column}" />
</f:facet>
<p:commandButton type="push" onclick="#{user.loginname}DeleteConfirmation.show()" value="#{message.global_table_action_delete}" image="ui-icon-trash">
<f:setPropertyActionListener value="#{user}" target="#{userAdministrationController.selectedUser}" />
</p:commandButton>
<!-- 1. WORKS FINE, STORED VALUE IS "loginname" -->
<c:set var="deleteConfirmationMessage" value="#{user.loginname}"></c:set>
<!-- 2. VALUE IS "!!!" AND NOT "loginname !!!" -->
<c:set var="deleteConfirmationMessage2">
<h:outputText value="#{user.loginname}" />!!!
</c:set>
<!-- 3. WORKS FINE (OUTPUT "loginname") -->
<h:outputText value="#{user.loginname}" />
<p:confirmDialog message="#{deleteConfirmationMessage}" header="#{message.user_dialog_delete_confirmation_title}" severity="alert" widgetVar="#{user.loginname}DeleteConfirmation">
<p:commandButton value="#{message.user_dialog_delete_confirmation_no}" onclick="#{user.loginname}DeleteConfirmation.hide()" update="#form" type="button" />
</p:confirmDialog>
</p:column>
Why does the case 2 not work properly?
<!-- 2. VALUE IS "!!!" AND NOT "loginname !!!" -->
<c:set var="deleteConfirmationMessage2">
<h:outputText value="#{user.loginname}" />!!!
</c:set>
That's because taghandlers and UI components doesn't run at the same time. JSTL tags are taghandlers and they run during building the view (when the XHTML file is converted to JSF component tree). JSF <h:xxx> tags are UI components and they run during rendering the view (when the JSF component tree is converted/rendered to HTML code). See also JSTL in JSF2 Facelets... makes sense?
So, when the <c:set> runs, the <h:outputText> hasn't run at all.
But in this particular construct you actually don't need the <h:outputText> at all. Apart from setting it as value of <c:set>, you could also just inline the EL expression raw in the template text (note that this works when using JSF with Facelets, not when using JSF with JSP; given the fact that you're using PrimeFaces, you're definitely using Facelets as PrimeFaces doesn't have a JSP taglib at all).
<c:set var="deleteConfirmationMessage2">
#{user.loginname}!!!
</c:set>
or perhaps you weren't aware that you can mix EL and plain strings in an attribute like
<c:set var="deleteConfirmationMessage2" value="#{user.loginname}!!!" />
or
<p:confirmDialog message="#{user.loginname}!!!">
Depending on the concrete functional requirement, which isn't exactly clear from the question, a different alternative may be to use the <o:cache> component of OmniFaces. This may be more useful if you intend to cache the value for a broader scope than just the page/request scope like as in your <c:set> examples.
Just making an educated guess, because I haven't tried to combine JSF and JSTL, but I believe the c:set would be handled before the h:outputText is rendered, so it would only see the static text in its body. I'm not sure what order tag handlers are called in relation to the JSF lifecycle but putting in some logging would clear that up.
xmlns:c="http://java.sun.com/jstl/core"
just add this as taglib for jstl

Resources