Lightweight Requests with PartialSubmit

Core JSF Ajax implementation and PrimeFaces serializes the whole form to build the post data in ajax requests so the same data is posted just like in a non-ajax request. This has a downside in large views where you only need to process/execute a minor part of the view. Assume you have a form with 100 input fields, there is an input field with ajaxbehavior attached processing only itself(@this) and then updates another field onblur. Although only a particular input field is processed, whole form data will be posted with the unnecessary information that would be ignored during server side processing but consume resources.

Upon request of an Enterprise PrimeFaces User who have large JSF pages and trying to reduce the network load, we’ve added partialSubmit feature to PrimeFaces Ajax extensions. This attribute is available in p:ajax and ajax enabled components like buttons, links and more. When enabled and partial processing is defined, only the partially processed components are added to the post data and rest in the same form are ignored. Here is an example;

<h:form id="form">

    <p:log />

    <h:panelGrid columns="5" cellpadding="5">
        <h:outputLabel for="name" value="Name:" style="font-weight:bold"/>

        <p:inputText id="name" value="#{pprBean.firstname}" />

        <p:commandButton value="Default" update="display" />

        <p:commandButton value="Partial" update="display" partialSubmit="true" process="name"/>

        <h:outputText value="#{pprBean.firstname}" id="display" />
    </h:panelGrid>

    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputText />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <p:inputTextarea />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />
    <h:selectOneMenu />
    <br />

</h:form>

Compare the post data;

Default

javax.faces.partial.ajax=true&javax.faces.source=form%3Aj_idt17&javax.faces.partial.execute=%40all
&javax.faces.partial.render=form%3Adisplay&form%3Aj_idt17=form%3Aj_idt17&form=form&form%3Aname=
&form%3Aj_idt18=&form%3Aj_idt125=&form%3Aj_idt19=&form%3Aj_idt21=&form%3Aj_idt23=&form%3Aj_idt25=
&form%3Aj_idt27=&form%3Aj_idt29=&form%3Aj_idt31=&form%3Aj_idt33=&form%3Aj_idt35=&form%3Aj_idt37=
&form%3Aj_idt39=&form%3Aj_idt41=&form%3Aj_idt43=&form%3Aj_idt45=&form%3Aj_idt47=&form%3Aj_idt61=
&form%3Aj_idt63=&form%3Aj_idt65=&form%3Aj_idt67=&form%3Aj_idt69=&form%3Aj_idt71=&form%3Aj_idt73=
&form%3Aj_idt75=&form%3Aj_idt77=&form%3Aj_idt79=&form%3Aj_idt81=&form%3Aj_idt83=&form%3Aj_idt85=
&form%3Aj_idt87=&form%3Aj_idt89=&form%3Aj_idt91=&form%3Aj_idt93=
&javax.faces.ViewState=140664906657838629%3A-6619052145563305617

Partial

javax.faces.partial.ajax=true&javax.faces.source=form%3Aj_idt124&javax.faces.partial.execute=form%3Aname
&javax.faces.partial.render=form%3Adisplay&form%3Aj_idt124=form%3Aj_idt124&form%3Aname=
&javax.faces.ViewState=140664906657838629%3A-6619052145563305617

End result is same however partialSubmit is significantly more lightweight and difference becomes larger as the form grows with more components. Check out the live demo of partialSubmit and compare the post data displayed in Log components. Once our implementation is solid and stable we have plans to enable partialSubmit by default.

This is one of the 2 new ajax features of 3.3 we’ve mentioned before, stay tuned for the second one. It’s really cool!

Update: partialSubmit will be true by default if there are partially processed components defined.

This entry was posted in PrimeFaces. Bookmark the permalink.

16 thoughts on “Lightweight Requests with PartialSubmit

  1. Hello Cagatay,

    The main goal of this feature was to reduce network traffic. Right? It would be also really interesting to compare the time of request preparation (in ms) in both approaches. Can you do this? :-) . Thanks.

  2. This is great feature, but isn’t partialSubmit attribute more superfluous. Can this be done in the manner: If process set, then do partial submit, else submit whole form.

    • The default behaviour of JSF should not be changed. Maybe someone reads other params from request while partial processing..

  3. Wait … Should the first button have process=”name” for the correct test right?

    • Doesn’t matter, will be same. Still I should add a 3rd button with process and not partialSubmit.

  4. Interesting concept/feature/component. I tested the showcase sample and had a question about test results. I’ll have to create a forum topic and ask there. :)

  5. Are there plans for AutoComplete to implement the interface AjaxSource so it supports partialSubmit as well?

  6. @Pelz Rutsche. AutoComplete “query” suggestions requests are out at the moment. No support of this feature. PrimeFaces should make sure, that also internal ajax requests offer a support for this great feature.