6 Replies Latest reply on May 7, 2007 7:55 PM by mail2bansi

    Ajax4JSF Perfomance Issues

    mail2bansi

      Me & my team have used Ajax4JSF extensively in our application very recently we have been observing perfomance problems.

      Here is the situation

      We have following dropdown defined with ajax4jsf event onchange

      <h:panelGrid columns="3" styleClass="detail" columnClasses="label">
       <h:outputText value="Manufacturer" />
      
       <h:selectOneMenu id="manufList" value="#{manufacturerBean.selectedManufacturer}" >
       <f:selectItem itemLabel="New" itemValue="New" />
      
       <f:selectItems value="#{manufacturerBean.manufacturerList}" />
       <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />
       </h:selectOneMenu>
       </h:panelGrid>
      


      The perfomance issue is whenever we pick a different value from the dropdown list Ajax4JSF onchange event is fired & the action method "loadManufacturerDetails" is invoked in the backing bean. This is perfect & expected behaviour. But prior to invoking onchange action method it invokes f:selectItems value binding method i.e. getManufacturerList in the backing bean which leads to perfomance issues as it goes thru Spring & Hibernate and hits the database & fires the query to get the List of Manufacturers everytime onchange event occurs & we were very much suprised with the wait time to populates other fields in the form

      Any pointers/suggestions will be highly appreciated

      Regards
      Bansi


        • 1. Re: Ajax4JSF Perfomance Issues

          If you know that the data is not changed while user selects data from the suggestion box, why your #{manufacturerBean.loadManufacturerDetails} method perform so many server side operations?

          What happens if you temporary remove a4j:support and add regular < h:commandButton value="Manual Update" / > does this method starts to work faster?

          • 2. Re: Ajax4JSF Perfomance Issues
            mail2bansi

            Sergey good point even i have the same point hence posted on the forum i.e. if the data is not changing then why is the dropdown always trying to get populated from the database. Is it due to the method call in the f:selectItems which calls the database i.e. <f:selectItems value="#{manufacturerBean.manufacturerList}" />

            Here are my observations from Log file
            Whenever i pick a different value from the dropdown as expected a4j onchange event fires & calls its action method "loadManufacturerDetails" i.e.
            <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />

            But
            Before and After onchange event database call occurs i.e. the following method gets called
            <f:selectItems value="#{manufacturerBean.manufacturerList}" />


            As suggested i can try emoving a4j:support & use valueListener for <h:selectOneMenu> but as we have used Ajax4JSF extensively we wanna optimize with a4j:support in place.

            • 3. Re: Ajax4JSF Perfomance Issues
              mail2bansi

              Not sure if i was clear in the above posting hence rephrase

              Here is the situation

              I have the following dropdown defined with ajax4jsf event onchange

              Code:

              <h:panelGrid columns="3" styleClass="detail" columnClasses="label">
              <h:outputText value="Manufacturer" />

              <h:selectOneMenu id="manufList" value="#{manufacturerBean.selectedManufacturer}" >
              <f:selectItem itemLabel="New" itemValue="New" />

              <f:selectItems value="#{manufacturerBean.manufacturerList}" />
              <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />
              </h:selectOneMenu>
              </h:panelGrid>

              The perfomance issue is

              Whenever i pick a different value from the dropdown, i expect only ajax4jsf action method is called i.e.

              <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />

              BUT why is the method defined in f:selectItems is getting called
              twice as seen in log file
              <f:selectItems value="#{manufacturerBean.manufacturerList}" />

              Logs:
              2007-05-04 14:16:31,694 INFO [com.boeing.nmt.nams.view.bean.ManufacturerBean] - < *** In getManufacturerList Backing Bean*** >
              Any pointers/suggestions will be highly appreciated

              Regards
              Bansi

              • 4. Re: Ajax4JSF Perfomance Issues

                Bansi, this is expected behavior of JSF runtime. During decode we have some input string coming from selectOneMenu , but we need to transform it to one of the elements of list that coming from selectItems. JSF do not hold list between requests and actually call binding behind value attribute to obtain list of items.
                You need to avoid excessive calls to database in case of "seldom modified" lists, like your case. Use one or another buffering technique or cache. Simplest approach will be just to use session (or application) scope bean and buffer list in that bean initializing it on the first call.
                You need to use same technique regardless of web technology you use.

                • 5. Re: Ajax4JSF Perfomance Issues
                  mail2bansi

                  Hi ishabalov
                  Thank you so much for wonderful explaination. The dropdown list which i mentioned performs CRUD operation.
                  The dropdown has a "New" value which allows the users to enter new values into form fields & performs Create/Insert operation whereas users pick other values from the dropdown which dynamically populates other fields in the form thereby facilitates to perform Update/Delete operation. The problem is whenever i pick a value from the dropdown list the database call happens twice.

                  Here is the dropdown

                   <h:selectOneMenu id="manufList" value="#{manufacturerBean.selectedManufacturer}" >
                   <f:selectItem itemLabel="New" itemValue="New" />
                   <f:selectItems value="#{manufacturerBean.manufacturerList}" />
                   <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />
                   </h:selectOneMenu>
                   </h:panelGrid>
                  


                  Here is the sequence of method calls whenever i pick a value from the dropdown list
                  - First time the method in f:selectItems gets called which results in a database call
                  <f:selectItems value="#{manufacturerBean.manufacturerList}" />
                  - Second time Ajax4JSF onchange event action method gets called .
                  <a4j:support action="#{manufacturerBean.loadManufacturerDetails}" event="onchange" reRender="manufName,manufDescription,manufSource,btnSave,btnDelete" />
                  - Third time again the method in f:selectItems gets called which results in a database call
                  <f:selectItems value="#{manufacturerBean.manufacturerList}" />

                  Here are my concerns
                  - Just picking a value from the dropdown shouldn't result in a call to database especially when there are no changes made to database

                  - I expect the calls to database happens ONLY in case of users click Save/Update/Delete buttons i.e. dropdown dynamically refreshes with database values

                  Any pointers/suggestions will be highly appreciated

                  Regards
                  Bansi

                  • 6. Re: Ajax4JSF Perfomance Issues
                    mail2bansi

                    Further to my posting here is the log snippets which substantiates that whenever i pick a value from dropdown
                    database call occurs twice

                    ********** FIRST METHOD CALL ***************************
                    2007-05-07 16:46:46,002 INFO [com.boeing.nmt.nams.view.bean.ManufacturerBean] - < *** In getManufacturerList Backing Bean*** >
                    2007-05-07 16:46:46,002 INFO [com.boeing.nmt.nams.service.impl.ManufacturerManagerImpl] - < *** In getManufacturerList Spring*** >
                    Hibernate: select namsmanufa0_.ID as ID60_, namsmanufa0_.CHANGE_USER as CHANGE2_60_, namsmanufa0_.NAME as NAME60_, namsmanufa0_.DESCRIPTION as DESCRIPT4_60_, namsmanufa0_.SOURCE as SOURCE60_, namsmanufa0_.STATUS as STATUS60_, namsmanufa0_.CHANGE_DATE as CHANGE7_60_ from NAMS_MANUFACTURER namsmanufa0_
                    
                    ********** SECOND METHOD CALL ***************************
                    2007-05-07 16:46:46,237 INFO [com.boeing.nmt.nams.view.bean.ManufacturerBean] - < *** In loadManufacturerDetails method *** >
                    Hibernate: select namsmanufa0_.ID as ID60_0_, namsmanufa0_.CHANGE_USER as CHANGE2_60_0_, namsmanufa0_.NAME as NAME60_0_, namsmanufa0_.DESCRIPTION as DESCRIPT4_60_0_, namsmanufa0_.SOURCE as SOURCE60_0_, namsmanufa0_.STATUS as STATUS60_0_, namsmanufa0_.CHANGE_DATE as CHANGE7_60_0_ from NAMS_MANUFACTURER namsmanufa0_ where namsmanufa0_.ID=?
                    
                    ********** THIRD METHOD CALL ***************************
                    2007-05-07 16:46:46,565 INFO [com.boeing.nmt.nams.view.bean.ManufacturerBean] - < *** In getManufacturerList Backing Bean*** >
                    2007-05-07 16:46:46,565 INFO [com.boeing.nmt.nams.service.impl.ManufacturerManagerImpl] - < *** In getManufacturerList Spring*** >
                    Hibernate: select namsmanufa0_.ID as ID60_, namsmanufa0_.CHANGE_USER as CHANGE2_60_, namsmanufa0_.NAME as NAME60_, namsmanufa0_.DESCRIPTION as DESCRIPT4_60_, namsmanufa0_.SOURCE as SOURCE60_, namsmanufa0_.STATUS as STATUS60_, namsmanufa0_.CHANGE_DATE as CHANGE7_60_ from NAMS_MANUFACTURER namsmanufa0_
                    

                    I do have Managed Bean in Session scope

                    Regards
                    Bansi