Workaround for Perfomance Problems with Data containers

/*****
 *** Workaround for Perfomance Problems with Data containers
 ***
 *** Prevents multiple recalculation during JSF
 *** lifecycle & partial refresh if not required
 ***
 *** Works for all data containers like repeat controls,
 *** data tables etc.
 ***
 *** UPDATE, 06/03/2012, 13:11:
 *** Works currently only with serializable data.
 ***
 *****/
 

function calculate(){
	/*** add your own code here ***/
}

/*** change client id if required ***/
var clientId = getClientId( this.id );
var keyId = "fixData-" + clientId;
var data = null;

/*** If data were never calculated before, calculate them **/
if( viewScope.containsKey( keyId ) === false){
   data = calculate();
   viewScope.put( keyId, data );
   return data;
}

/*** Check for partial refreshs and refreshed id ***/
if( com.ibm.xsp.ajax.AjaxUtil.isAjaxPartialRefresh(facesContext) === true ){
   var rId = com.ibm.xsp.ajax.AjaxUtil.getAjaxComponentId( facesContext  );
   if( rId !== clientId )
	return viewScope.get( keyId );
}


/*** Prevent multiple calculation during JSF lifecycle ***/
if( requestScope.containsKey( keyId ) == true ){
	value = viewScope.get( keyId );
}else{
	value = calculate();
	viewScope.put( keyId , value );
	requestScope.put( keyId , true );
}

value





UPDATE, 06/03/2012, 13:23:
Updated example.

UPDATE, 06/03/2012, 13:11:
Works currently only with serializable data.

This snippet can increase the XPages performance by preventing data containers (like repeat controls, data tables) to be recalculated if not required.
The code has to be added to SSJS in the <xp:this.value></xp:this.value> section of the data container.

Here is an example how to use:

*** Old Code ***

<xp:repeat id="repeat1" rows="30">
  <xp:this.value><![CDATA[#{javascript:
     var test = new java.util.Vector();
     test.add( java.lang.System.currentTimeMillis() )
     return test;
  }]]></xp:this.value>
</xp:repeat>

*** New Code ***

<xp:repeat id="repeat1" rows="30">
  <xp:this.value><![CDATA[#{javascript:
     function calculate(){
        var test = new java.util.Vector();
        test.add( java.lang.System.currentTimeMillis() )
        return test;
     }

     /*** change client id if required ***/
     var clientId = getClientId( this.id );
     var keyId = "fixData-" + clientId;
     var data = null;

     /*** If data were never calculated before, calculate them **/
     if( viewScope.containsKey( keyId ) === false){
       data = calculate();
        viewScope.put( keyId, data );
        return data;
     }

     /*** Check for partial refreshs and refreshed id ***/
     if( com.ibm.xsp.ajax.AjaxUtil.isAjaxPartialRefresh(facesContext) === true ){
        var rId = com.ibm.xsp.ajax.AjaxUtil.getAjaxComponentId( facesContext  );
        if( rId !== clientId )
     return viewScope.get( keyId );
     }


     /*** Prevent multiple calculation during JSF lifecycle ***/
     if( requestScope.containsKey( keyId ) == true ){
        value = viewScope.get( keyId );
     }else{
        value = calculate();
        viewScope.put( keyId , value );
        requestScope.put( keyId , true );
     }

     value
  }]]></xp:this.value>
</xp:repeat>

*** See here for more details ***
http://www-10.lotus.com/ldd/xpagesforum.nsf/topicThread.xsp?action=openDocument&documentId=56E9B8537DA50A90852579A6002EAC64
http://atnotes.de/index.php?topic=53754.0
http://hasselba.ch/blog/?p=572

JavaScript (Server)
Sven Hasselbach
March 6, 2012 5:12 AM
Rating
22

All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.



1 comment(s)Login first to comment...
Sven Hasselbach
(at 15:15 on 07.03.2012)
@Tony McGuckin:
Maybe for repeat controls, but data context variables don't have these options (as far as I know)