19
votes

I'm working on a WebApp using JSF 2.2 + Primefaces... project is growing fast, and first performance test was very poor (due to my poor knowledge on JSF lifecycle in combination to non-functional requirements - i.e. fully ajax website), then we could improve a little but results still, are not as expected. (We are having a time of 300~1500 ms depending on the action, idea is to have a performance around 500ms, give or take). Mainly the Restore View phase and the Render Response are the time consumers (on other phases, time spent is worthless). For some actions, Invoke Application also takes time (due to DB calls).

After reading lots of articles on the web, there were a lot of awesome tips to be taken into account (many of course from StackOverflow) such as:

  • Improving DB queries

we have some complex ones which are done with two Hibernate Criteria queries so we have to work here. (maybe use pure SQL queries, and on complex ones use sub-querying?)

  • Never defining business logic on Bean's getters

Got It!

  • Setting the appropriate scopes to bean and storing on them nothing more than the necessary stuff

We have a full ajax site, so View Scoped are almost as Session Scoped to us, we are using the SessionBeans as a sort of 'Cache' to store key data which we don't want to get from DB every time + define businesses logic here.

  • Choosing the right State saving method of JSF - Client Vs Server

For this, I have to research some more, check on the possibilities with their pros and cons, then test performance on each one.

So far very clear, now some extra tips on which I have some doubts.

  • Use vanilla HTML as much as possible, and preferably use h: tags rather than p: tags

Plain HTML is clear and make sense, now between h: and p: how much is it worthy? For example.

<p:commandButton value="Value" 
             styleClass="class" 
             actionListener="#{myBean.doStuff()}"
             ajax="true" process="@form" update="@form" 
             onsuccess="jsFunction()" />

vs

<h:commandButton value="Value" 
             styleClass="class" 
             actionListener="#{myBean.doStuff()}" >
       <f:ajax execute="@form" render="@form" event="onclick" />
</h:commandButton>

or

<ui:fragment... vs <p:fragment...

or

<p:outputLabel value="#{myBean.value}" rendered="#{myBean.shouldRender}" />

vs

<ui:fragment rendered="#{myBean.shouldRender}">
    <label>#{myBean.value}</label>
</ui:fragment>

I've been using a mix of Primefaces with Jsf tags and some plain HTML here and there for a while now.(mainly PF due to their component's features) I now that plain HTML will always be faster, but between JSF and another Framework? If I go for this, changing it will take plenty of time and I wouldn't like the outcome of knowing it doesn't make a relevant difference at all.

  • Custom Facelets tags vs Composite Components

I think here's the key. Still have some doubts about their differences, on the implementation of both, CC are pretty simple and flexible to use but have the disadvantage that they are fully included on the ViewTree and JSF re-generates for each request (if I'm not mistaken), while custom tags seems a little bit more complex to use (not that much) but has the advantage that only what is actually rendered is included on the ViewTree and nothing more, making the RESTORE VIEW less time consuming. We have several composite components and none Facelets Tags, so here it will be much of the work to do. I still haven't found a good article explaining differences on them, when one should be used and when the other one (have read that for inputs, messages use TAGS and for more complex things CC). If the idea is to prefer tags vs CC, which would be the case on which I would have no option rather than using CC? Is it ok to use custom tags inside CC to make them lighter to JSF for processing them?

I'm about to get into a journey of modifying hole project in order to get a better performance which will take me a couple of days, idea is to get better results this time; so every tip, advice and suggestion is very welcomed! Thanks for your time guys!

6
I would start by measuring where the 300~1500 ms are spent so you know what needs to be improved. As a start you can use a PhaseListener to measure how much is spent in each phase, that would give an vague idea whether the structure of the page or the access to the database is responsible for the delays depending on which phase is most costly. Also if you have a DAO layer, you could use some aspect to log calls into this layer to measure database costs.Diego
@Diego sorry diego, I forgot to add this on my question. Of course I've been measuring with a profiler. Render Response and Restore View are taking 98% of the timeRodrigo Martinez
If you have a lot of inputs or complex ones, try using PF partial submit on the ajax calls, saves a lot of time, and also try what the using the process attribute can do...Kukeltje
And also check if you actually need to update the full form after the 'doStuff()'. If components know which other components to update in the ajax calls you most likely do not have to update the form at all, unless you have to replace the page fullyKukeltje
This is really too broad for Stack Overflow. It reads almost like a blog not a question. Profile and naildown the top performance consumer and ask a question about specifically it if you can't figure how to improve it. Rinse and repeat.BalusC

6 Answers

3
votes

There are a couple of things you can do to improve performance of your screens

  1. GZIP filter will reduce the initial load time significantly. It compresses the page contents while transferring to client browser. Refer to https://stackoverflow.com/a/35567295/5076414
  2. You can additionally implement a cacheFilter to bring performance of your screens at par with JavaScript based UI. This will cache the static content of your screen such as icons, images, stylesheets, javascripts etc. You can control what to cache and what to exclude. Refer to https://stackoverflow.com/a/35567540/5076414
  3. For client side UI components, you can use Primefaces which is JQuery based UI.

How to verify if my screen is using gzip and cache

To see if your contents are already usign gzip and cache, In your Google Chrome Browser -> right click on your screen -> inspect -> click network tab -> refresh your screen. Click on the images, icons, stylesheets and see if you see following in response header

Cache-Control:max-age=2592000 if the status of element is 304 (coming from cache)

Content-Encoding:gzip if the status of element is 200

2
votes

RenderResponse takes 98% of your time because... that's what JSF mainly does. I'd be worried if JSF dedicated 50% of a request's processing time to do things other than rendering the response! You need to dig deeper. Consider this example.

Say you have a page that displays a table. You use the p:dataTable PrimeFaces component, like this:

<h:html>
   <h:body>
       <p:dataTable value="#{myBean.data}">
       </p:dataTable>
   </h:body>
</h:html>

And you have this @ManagedBean:

@ManagedBean(name="myBean")
public class MyBean {

    public List<MyObject> getData() { 
        return // fetch list from database;
    }
}

Every time getData() is called, there's a database access, and that time adds to the global time of the render phase. Moreover, the rendering of p:dataTable might require many calls to getData.

Again, you need to dig deeper into you application and detect where exactly, during the render phase, is time being spent. In my experience, naive implementations of @ManagedBeans have a lot of database-querying code in the same getters referenced in the xhtmls, like in my previous example. JSF (or a component like PrimeFaces' p:dataTable) might invoke those getters many times while rendering a single xhtml. A common strategy is fetching data only once, using the preRenderView event, like this:

In your xhtml:

<h:html>
   <f:metadata>
       <f:event type="preRenderView" listener="#{myBean.fetchDAta}"/>
   </f:metadata>
   <h:body>
       <p:dataTable value="#{myBean.data}">
       </p:dataTable>
   </h:body>
</h:html>

In your managed bean:

@ManagedBean(name="myBean")
public class MyBean {
    private List<MyObject> data;

    public void fetchData() {
         data = // fetch data from database.
    }

    public List<MyObject> getData() { 
        return data; 
    }
 }
2
votes

I faced the same problem half a year ago. Most of the time spent in RestoreView and RenderResponse phase. If your problem is the same then there is no much you can do:

  1. Use partialSubmit="true" as much as possible
  2. use the execute (or PrimeFaces process) attribute to reduce processing on the server side
  3. Reduce the number of components
  4. Do not use composite components a lot

In my particular case I had a lot of dynamic html without input controls and I used composite component as a template for conditional rendering. To increase performance I used freemarker to generate dynamic html.

PS. My opinion is not to use JSF if we you have complex pages with many components. I think Tapestry is more optimized for this. It doesn't recreate components on every request as JSF does.

-2
votes

I am not sure if there is a big difference between "p" and "h" since both of them are rendered as html by the end. I see you use a lot the process attribute. You may can target specific ids in this attribute to improve perfomance by sending only parts of the form. Another idea to increase performance is to use the primefaces "cache". http://www.primefaces.org/showcase/ui/misc/cache.xhtml for non dynamic content that you want to be rendered very frequently (check the documentation). I guess "cache" will try to fetch the treeview from cache instead of reconstructing it.

-2
votes

ıf you want make jsf application with other framework your application is poor as performance for users. Because Jsf application became 6 phase that wait render phase too much. So you can use micro services for backend and use javascript for frontend. Result you can make so good application as performance and architecture. you can look spring boot micro services for java ee applications

-3
votes

I read an interesting article about JSF speed up performance. In restore view phase, JSF reconstructs the component tree including binding data to data tables causing unnecessary fetches of data from the database. The article looks at one way of avoiding the additional work to fetch the data.

I report the possible solution here, and the full article for reference.

A solution for the problem is to skip fetching the data the first time altogether. It isn’t needed, it isn’t even used and it isn’t even the correct data (don’t worry, I’ll explain that later). In the FacesContext object there is a method called getRenderResponse() which returns true if the render response method has been called and we are in the rendering phase. Until we are rendering the page, we don’t really need our data so we only load it if this method returns true.

For example:

//generates the list of data, think of this as an expensive DB operation
private List<Integer> generateData()  {
if (!FacesContext.getCurrentInstance().getRenderResponse()) {
    return null;
}
System.out.println("Generating Data starting from "+pageNumber);
...
...
...
}

So we only get one data fetch per page request even on postbacks because we don’t bother loading the data until we really need it in the render response and if you look at the timing, our pages are loading twice as fast since we only fetch half the data.

So there you go, you can increase the speed of your JSF pages by only loading data when you really need it, I guess kind of lazy lazy loading data.

Double the speed of (some of) your JSF pages (and dodge bugs too)

I hope it is useful to others.