2

I use Mojarra implementation of JSF (version 2.2.1). I have a big problem with performance during ajax requests.

My page has a lot of components so I understand why first rendering takes much time, but what with ajax requests?

They takes also a lot of time although they do almost nothing. Here is my simplified example:

In below example pressing "performance test" button takes several ms:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:body>
        Hello World
        <h:form>
            <h:commandButton value="performance test">
                <f:ajax execute="@this" render="@none" />
            </h:commandButton>
        </h:form>
    </h:body>
 </html>

But if add 1000 <h:inputText /> elements to the <h:form></h:form> the same action takes over 100ms !

I have checked that 80% of time is consumed in RESTORE_VIEW phase, 20 % in RENDER_RESPONSE phase, rest of phases do not take significant amount of time.

Is there any possibility to fix it?

I tried also to disable javax.faces.PARTIAL_STATE_SAVING (memory consumption is not the problem in my case) but also without any success.

EDIT: A thousand of <h:inputText> added to a <h:form> was only a simplified example. I just wanted to emphasize the fact that big amount of components has significant influence on the ajax request (that does almost nothing) - which is a severe problem on my website.

In the reality, of course, I don't have 1000 inputs. I display very big table with a lot of data - if data is empty in any cell there should by an hyphen instead. I used composite component for that - where I had more than one ui:fragment with render=true/false

Today I tried to use my own component instead of composite one - and response time and memory usage have decreased.

But I'm still not satisfied because my very simple ajax request on that page takes much more time than the same ajax request used on another - thinner page (i.e. with less number of components). Isn't it any JSF architecture issue?

chrosciu
  • 304
  • 3
  • 9
  • 1
    100ms for a monster form with 1K input fields is very neat. On the other hand, I wonder who ever fills such a monster form. Perhaps you need to introduce some searching/filtering system like as Google does? Google is also not showing all zillion results at once without any form of searching/filtering. – BalusC Aug 11 '13 at 21:20
  • Would it be an option to switch the JSF implementation to MyFaces? According to this blog http://blog.oio.de/2013/04/08/jsf-comparison-myfaces-vs-mojarra/ the implementation (Mojarra vs MyFaces) does have an impact when facing big component trees. – cheffe Aug 12 '13 at 17:02
  • @BalusC: Thanks for your reply. Please see edit section in my question - I refined description of my problem. – chrosciu Aug 12 '13 at 18:17
  • @cheffe: Thanks for your reply. I have read this article - this was a bug which has been corrected, see: http://blog.oio.de/2013/05/16/jsf-performance-mojarra-improves-dramatically-with-latest-release/ – chrosciu Aug 12 '13 at 18:18
  • You told nowhere that you were using a composite. They are known to have a measurable performance impact. See also http://stackoverflow.com/questions/6822000/when-to-use-uiinclude-tag-files-composite-components-and-or-custom-componen/6822269#6822269 for some guidelines and hints. A composite component for the sole purpose of conditional rendering is kind of weird. Better use a tagfile if all you need is to eliminate code duplication. – BalusC Aug 12 '13 at 18:26
  • @BalusC: You are right. Thanks for this precious link. However can we come back once more to the main question? "Why very simple ajax request on big page takes much more time than the same ajax request used on another - thinner page (i.e. with less number of components)?" Can you add sth to mrembisz's answer? (please see his edit section) – chrosciu Aug 13 '13 at 19:18

1 Answers1

1

Not really, JSF always rebuilds the entire component tree in restore view phase. You would do better with <ui:repeat> in this case but I realize your test is artificial and real page could have a lot of unique components.

There are quite a few ways to reduce the amount of components, like mentioned <ui:repeat>. Also you can use plain html in your facelets. Chunks of html free of JSF tags are represented as a single UIInstructions component. Still you can use EL expressions in there. It is hard to recommend something particular without more details of your problematic scenario.

EDIT: Component tree is restored top-bottom, no idea whether it's feasible to somehow optimize it and skip parts not needed by a request. The problem is you don't know in which part of the component tree nodes with particular id specified in ajax tag would be, you can only attempt some optimizations. Looks like the authors did not consider these complications worth the effort.

As for multiple conditional sections - I haven't found anything directly supporting this in JSF. A dedicated custom component sounds like the best bet here. We did something similar, our own implementation of <ui:include>, which supports dynamic src attribute working inside <ui:repeat>.

mrembisz
  • 12,722
  • 7
  • 36
  • 32
  • I used your advice - please see edit section in my question. But what for "JSF always rebuilds the entire component tree in restore view phase"? It takes a lot of valuable processor time when unnessesary (in my opinion). – chrosciu Aug 12 '13 at 18:19
  • There is no architectural issue with JSF. I think it is a bug in Mojarra. Try MyFaces 2.1.x instead and you'll see the difference. The implementation in MyFaces for composite components is totally different from the one in Mojarra. There is an small impact when using composite components, but most of the time it really pays off. – lu4242 Aug 13 '13 at 14:25