2 Replies Latest reply on Nov 19, 2009 11:49 AM by gonzalad

    performance pb with big datatable

    gonzalad Apprentice

      Hello,

      I have perfomance problems when showing a 500 rows table in ajax mode.
      The performance problem appears on the browser (I think it's due when RF tries to include the ajax response in the DOM or when it parses the XML response).
      Rendering all the 500 lines (339 ko) takes :
      * 2 s on the server.
      * 4s on FF and 5.5 s on IE6
      Appserver and browser are running on the same host.

      You can see a screen capture of my page : http://www.flickr.com/photos/44793303@N04/4116400761/sizes/o/.

      When I ask for 20 rows, table is displayed quite instantaneous (200 ms).

      I know 339 ko is a lot of data.
      Should I exclude ajax usage (replace a4j:commandButton with h:commandButton) in this particular case ?
      If yes, and in order to know this in the future, what's the best practice for a reasonable maximum ajax payload (50 ko, 100ko, 1Mo ?).

      Thanks very very much for your input !


      More details

      Using Page Speed Activity Tab (Google Page Speed plugin for FF), javascript executions takes between 1 and 2 seconds.
      See http://www.flickr.com/photos/44793303@N04/4117274650/sizes/o/.
      For more info about Page Speed Activity usage, see http://code.google.com/intl/fr/speed/page-speed/docs/using.html#activities

      When using a4j:log, I see (I'm posting only the interesting part here) :

      debug[12:10:19,407]: Have Event [object Object] with properties: target: [object HTMLInputElement], srcElement: undefined, type: click
      debug[12:10:19,412]: QueryString: AJAXREQUEST=sR&sF=sF&sF%3Astatut=Tous&sF%3Anom=&sF%3Abadge=&sF%3Aj_id73=500&javax.faces.ViewState=j_id7&sF%3AdoFiltrer=sF%3AdoFiltrer&
      debug[12:10:21,503]: Response with content-type: text/xml;charset=UTF-8
      debug[12:10:21,505]: Full response content: ..blabla...
      debug[12:10:21,529]: call getElementById for id= rF
      debug[12:10:22,503]: Replace content of node by replaceChild()
      debug[12:10:22,820]: search for elements by name 'script' in element form
      debug[12:10:22,843]: No focus information in response


      And an extract of my page code :
      <a4j:region id="sR">
       <h:form id="sF">
       <a4j:commandButton id="doFiltrer" action="#{rechercherBeneficiaireAction.search}"
       reRender="rF,msg"
       limitToList="true"
       status="status2"
       value="#{messages['direction.beneficiaire.button.filtrer']}"/>
       </h:form>
      </a4j:region>
      
      <h:form id="rF">
       <rich:panel header="#{messages['titre.page.direction.liste.recherche.beneficiaire.titre']}" rendered="#{rechercherBeneficiaireAction.resultListNotEmpty}">
       <a4j:outputPanel id="bDt" rendered="#{rechercherBeneficiaireAction.resultListNotEmpty}">
       <table cellspacing="0" cellpadding="0" border="0" width="100%" class="rich-table">
       <colgroup span="9" />
       <thead>
       blabla (just some th info)
       </thead>
       <a4j:repeat var="utilisateur" value="#{rechercherBeneficiaireAction.resultList}" rowKeyVar="i">
       <tr class="#{i%2==0?'rich-table-cell-pair':'rich-table-cell-impair'}">
       <td class="rich-table-cell rich-table-cell-checkbox">
       <input type="checkbox" name="sel"/>
       </td>
       <td class="rich-table-cell">
       <img src="#{rechercherBeneficiaireAction.getStatutImgUrl(utilisateur)}"/>
       </td>
       <td class="rich-table-cell">
       <h:outputText value="#{utilisateur.personnePhysique.membre.departementClient.libelle}"/>
       </td>
       <td class="rich-table-cell">
       <a href="#{detailProfilUrl}&id=#{utilisateur.personnePhysique.membre.id}">#{utilisateur.login}</a>
       </td>
       <td class="rich-table-cell">
       <h:outputText value="#{el:abbreviate(utilisateur.personnePhysique.nom,19)} #{el:abbreviate(utilisateur.personnePhysique.prenom,19)}" title="${utilisateur.personnePhysique.nomPrenom}"/>
       </td>
       <td class="rich-table-cell">
       <h:outputText value="#{utilisateur.personnePhysique.membre.getBeneficiaireParProduitSouscrit(produitSouscritAction.instance).datePremiereCommande}">
       <s:convertDateTime pattern="#{messages['datePattern.libelle']}"/>
       </h:outputText>
       </td>
       <td class="rich-table-cell">
       <h:outputText value="#{utilisateur.personnePhysique.membre.getBeneficiaireParProduitSouscrit(produitSouscritAction.instance).recapCommandeBeneficiaire.nbTitres}" />
       </td>
       <td class="rich-table-cell">
       <h:outputText value="#{utilisateur.personnePhysique.membre.getBeneficiaireParProduitSouscrit(produitSouscritAction.instance).parametrageDotation.maxDemande}"/>
       </td>
       <td class="rich-table-cell">
       <s:fragment rendered="#{utilisateur.codeAction ne 'AT'}">
       <s:fragment rendered="#{!utilisateur.actif}"><a title="#{messages['bouton.activer']}" onclick="act(#{utilisateur.id})" href="#">#{messages['bouton.action.activer']}</a></s:fragment>
       <s:fragment rendered="#{utilisateur.actif}"><a title="#{messages['bouton.desactiver']}" onclick="des(#{utilisateur.id})" href="#">#{messages['bouton.action.desactiver']}</a></s:fragment>
       </s:fragment>
       <s:fragment rendered="#{utilisateur.codeAction eq 'AT'}"><a title="#{messages['bouton.valider']}" onclick="val(#{utilisateur.id})" href="#">#{messages['bouton.action.valider']}</a>
       <a title="#{messages['bouton.refuser']}" onclick="ref(#{utilisateur.id})" href="#">#{messages['bouton.action.refuser']}</a></s:fragment>
       </td>
       </tr>
       </a4j:repeat>
       </table>
       </a4j:outputPanel>
       </rich:panel>
      </h:form>
      





        • 1. Re: performance pb with big datatable
          gonzalad Apprentice

          When profiling javascript with firebug, I see :

          updatePagePart() call-count=2,percentage=38.56%,time=501ms,cumulative-time=1506ms
          clean() call-count=16298,percentage=22.25%,time=289.201ms,cumulative-time=688.548ms


          Do you think rewriting ajax part of AjaxScript with prototype or jQuery could significally improve response time ?

          Here's more detail :
          updatePagePart() 2 38.56% 501.292ms 1506.713ms 753.357ms 12.716ms 1493.997ms 3_2_2.SR...jaxScript (ligne 1304)
          clean() 16298 22.25% 289.201ms 688.548ms 0.042ms 0ms 688.323ms 3_2_2.SR...jaxScript (ligne 2737)
          applyCleaners() 16298 17.36% 225.654ms 399.347ms 0.025ms 0.021ms 0.342ms 3_2_2.SR...jaxScript (ligne 2731)
          (?)() 16298 6.83% 88.82ms 88.82ms 0.005ms 0.004ms 0.122ms 3_2_2.SR...jaxScript (ligne 2763)
          (?)() 16298 6.53% 84.873ms 84.873ms 0.005ms 0.004ms 0.292ms 3_2_2.SR...ypeScript (ligne 4338)
          clearChildNodes() 2 4.76% 61.919ms 61.919ms 30.96ms 0.05ms 61.869ms 3_2_2.SR...jaxScript (ligne 610)


          • 2. Re: performance pb with big datatable
            gonzalad Apprentice

            I'm using now a4j:log, and modified a bit AjaxScript js in order to add 4/5 additionnal log Statements.

            I've found some lines where we spend more than 1s.

            I've made 4 samples (in order to confirm the measurements).
            Log statements I've added :

            Sarissa.clearChildNodes
            window.RichFaces.Memory.clean

            These log statements are written after the code corresponding execution in updatePagePart method.

            I can put more more log statements if it can help improve reveling (or not) RF performance, but I need a little guidance now because I'm a javascript neewbie.
            Also, I would like to know if there's something to optimize here or if I'm following a bad path and should just stop here and search somewhere else.

            Thanks very much !


            1. call
            debug[17:33:36,098]: call getElementById for id= rF
            error[17:33:36,552]: window.RichFaces.Memory.clean
            error[17:33:36,616]: Sarissa.clearChildNodes
            debug[17:33:37,005]: Replace content of node by replaceChild()
            error[17:33:37,324]: anchor.replaceChild
            
            2. call
            debug[17:35:29,651]: call getElementById for id= rF
            error[17:35:30,093]: window.RichFaces.Memory.clean
            error[17:35:30,155]: Sarissa.clearChildNodes
            debug[17:35:30,539]: Replace content of node by replaceChild()
            error[17:35:30,858]: anchor.replaceChild
            
            3. call
            debug[17:36:07,527]: call getElementById for id= rF
            error[17:36:07,983]: window.RichFaces.Memory.clean
            error[17:36:08,050]: Sarissa.clearChildNodes
            debug[17:36:08,435]: Replace content of node by replaceChild()
            error[17:36:08,767]: anchor.replaceChild
            
            4. call
            debug[17:36:48,686]: Update page part from call parameter for ID rF
            debug[17:36:48,686]: call getElementById for id= rF
            error[17:36:49,145]: window.RichFaces.Memory.clean
            error[17:36:49,206]: Sarissa.clearChildNodes
            debug[17:36:49,595]: Replace content of node by replaceChild()
            error[17:36:49,914]: anchor.replaceChild