You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Leonardo Uribe <lu...@gmail.com> on 2012/01/18 16:26:09 UTC

[core] Improve PSS algorithm when a dynamic view (use of c:if or ui:include src=#{...}) is used

Hi

In the last months I have been working on a solution to improve Partial
State Saving (PSS) performance in cases where the view is updated
dynamically by effect of a facelet tags like:

- <c:if ...>
- <c:when>
- <ui:include src="#{...}">
- <ui:decorate template="#{...}">

In simple words, any use of the previous tags in a page causes all
components inside them to be saved and restored fully. The side effect is
the overall state gets bigger. With the introduction of PSS in JSF 2.0,
instead save an array of properties, a key/value pairs are used, so usually
this effect is difficult to notice, but it is relevant specially when
<ui:include src="#{...}"> is used to update content dynamically. It is
quite simple to find examples with a search engine on the internet.

I'll explain in detail what's going on.

Let's see what happen when c:if is used:

<c:if test="#{condition}">
    <h:outputText value="Some text"/>
</c:if>

The first time the view is rendered, if the condition is false, the
component is not added, but later in a postback if the condition changes
from false to true, the component is added. Here the algorithm have two
options:

1. Ignore it.
2. Mark the component or branch to be restored fully.

Most of the time ignore (1) is ok, but in some complex cases the state
synch is lost, because test="#{condition}" is evaluated every time the view
is restored, with different results. The users usually have reported this
as "state get lost" or ClassCastException problems. To deal with such
cases, a special mode was added in MyFaces to implement (2) with a web
config param called org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS.

But what happen if the algorithm save c:if "condition" the first time the
view is rendered? With that, PSS algorithm will always restore the initial
view as expected. Recently in 2.0.10 / 2.1.4, this improvement
(MYFACES-3329) was added so it is no longer necessary to enable the web
config param. Great! But note this does not solve the "state gets bigger"
problem.

Now consider what happen if c:if "condition" is saved every time it change
(before render response). If the condition is false and changes to true,
the initial state will now be restored including the
component, so if it is called markInitialState() over the component, and
then the delta is saved, the state size will be smaller and finally it will
be saved more efficently, because the initial state is the one who gets
bigger, instead the part that is saved as delta.

This solution can be applied to <c:if ...>, <c:when>, <ui:include
src="#{...}"> and <ui:decorate template="#{...}">, which is enough because
<c:forEach> can be replaced with <h:dataTable rowStatePreserved=true ...>
or a similar component like the ones available in Tomahawk or any other
variant. It is interesting to note the solution also fix the problem when
<h:dataTable rowStatePreserved=true ...> is used inside a dynamic part.

Fortunately, the spec doesn't say anything about how markInitialState() is
called, and let it as an implementation detail. Also,
javax.faces.IS_BUILDING_INITIAL_STATE description is so general that even
with the change there is no need to change the javadoc. After considering
all history behind PSS algorithm, it seems reasonable to activate
markInitialState() call and set javax.faces.IS_BUILDING_INITIAL_STATE to
true when a dynamic update in a component tree is done by a facelet tag,
and deactivate it as soon as the code process the content.

At the end, applications using the previous tags will have a really huge
improvement into its state. But anyway, since it is a "extension" of the
initial intention of the flag, I consider desirable to mention it. It is
difficult to measure the impact, because it depends of the view structure
itself, but it sounds like a very promising change.

Suggestions, opinions and what you do want to say about this proposed
change is welcome. If no objections, I'll commit the proposed change soon.

regards,

Leonardo Uribe