+ Start a Discussion
andrew_mowatandrew_mowat 

Tabbed Visualforce Page Performance Issues

Hi All,

 

We have a tabbed Visualforce page in our Force.com application that is loading quite a bit of data from a custom controller. This has the potential to slow down the page load quite dramatically as all of the data is loaded via methods in the controller, and all the tabs on the page (about 9 of them) render on page load.

 

I'm looking for a way to improve the performance.  Thoughts so far:

 

  • Move some of the queries into Ajax and have them execute onclick for each tab (never done Ajax so not sure about this)
  • Have some method of not rendering the contents of each tab on page load, only when the tab is selected

Can anyone provide some guidance here?

 

Cheers,

Andrew

 

Best Answer chosen by Admin (Salesforce Developers) 
andrew_mowatandrew_mowat

For anyone who might need to try this, I finally got it working.

 

I now don't load all of my tabs content on page load. I have a flag for each tab (other than the first one) that is set to false by default. For me, this improved things greatly as each tab returned some related data through a query, and if this returned a large data set, the page was taking a while to load.

 

I now have some ajax around ontabenter for each tab, which sets the rendered flag to true and rerenders the tab to get the data. While the tab is rerendering it shows a spinning gif.

 

Here is an example from the page:

 

  <apex:tab label="Fund Asset Classes" name="Fund_Asset_Class_Links" id="tabFundAssetClassLinks" rendered="{!or(FTTUserFlag,IRCUserFlag)}" ontabenter="refreshAssetClassTab()">

 

<apex:form >
                <apex:actionFunction name="refreshAssetClassTab" action="{!setAssetClassRenderFlag}" rerender="assetClasses" status="assetClassStatus"/>
            </apex:form>                                                        
                                   
            <apex:actionStatus id="assetClassStatus">
                <apex:facet name="start">
                    <apex:image value="/servlet/servlet.FileDownload?file=015T0000000FnsM" />                                 
                </apex:facet>
                <apex:facet name="stop">   

 

 <apex:pageBlock title="Fund Asset Classes" id="assetClasses">       

 

    <apex:pageblockTable value="{!allFundAssetClassLinks}" var="fundAssetClassLinks" width="100%" rendered="{!AssetClassRenderFlag}">                                                                     
                    // output what you want to see in the table

 

 

                </apex:pageblockTable>     
                </apex:pageBlock>      
                </apex:facet>
                
            </apex:actionStatus>
            
      </apex:tab>

 

and within the controller a simple set and get:

 

public Boolean getAssetClassRenderFlag() {
        return AssetClassRenderFlag;
    }    
    
    public void setAssetClassRenderFlag() {
        setFlagsFalse();
        AssetClassRenderFlag = true;
    }

 

The switchType on the tabPanel is set to client.

 

Hope this helps someone.

 

Andrew

All Answers

paul-lmipaul-lmi

what is the switchType attribute set for on your tabPanel?  some of these require all queries to run on page load, some only require them on tab load.

andrew_mowatandrew_mowat

Thanks for replying.

 

It was set to client. However have just tried server and ajax and it doesn't appear to have made any difference, all tabs are loaded.

 

If I specify ajax as the switch type, I take it I actually have to provide some ajax with which to do the switch??

paul-lmipaul-lmi

the platform handles each switchtype seamlessly, so no, you don't need to have any other special code to make that work.  if your org has the newer version of the debug log, you should be able to profile the "worst offenders" in your page to tune it better.  if it doesn't, open a support ticket to get it enabled.

andrew_mowatandrew_mowat

I think I know what methods are running the worst offending queries - my preference would be to not load them until they are needed.

 

Any thoughts on using the selectedTab and passing that through to the controller somehow, then only executing the method if the tab is selected?

paul-lmipaul-lmi

i don't have much experience with that flow, but maybe someone else can chime in there.

andrew_mowatandrew_mowat

For anyone who might need to try this, I finally got it working.

 

I now don't load all of my tabs content on page load. I have a flag for each tab (other than the first one) that is set to false by default. For me, this improved things greatly as each tab returned some related data through a query, and if this returned a large data set, the page was taking a while to load.

 

I now have some ajax around ontabenter for each tab, which sets the rendered flag to true and rerenders the tab to get the data. While the tab is rerendering it shows a spinning gif.

 

Here is an example from the page:

 

  <apex:tab label="Fund Asset Classes" name="Fund_Asset_Class_Links" id="tabFundAssetClassLinks" rendered="{!or(FTTUserFlag,IRCUserFlag)}" ontabenter="refreshAssetClassTab()">

 

<apex:form >
                <apex:actionFunction name="refreshAssetClassTab" action="{!setAssetClassRenderFlag}" rerender="assetClasses" status="assetClassStatus"/>
            </apex:form>                                                        
                                   
            <apex:actionStatus id="assetClassStatus">
                <apex:facet name="start">
                    <apex:image value="/servlet/servlet.FileDownload?file=015T0000000FnsM" />                                 
                </apex:facet>
                <apex:facet name="stop">   

 

 <apex:pageBlock title="Fund Asset Classes" id="assetClasses">       

 

    <apex:pageblockTable value="{!allFundAssetClassLinks}" var="fundAssetClassLinks" width="100%" rendered="{!AssetClassRenderFlag}">                                                                     
                    // output what you want to see in the table

 

 

                </apex:pageblockTable>     
                </apex:pageBlock>      
                </apex:facet>
                
            </apex:actionStatus>
            
      </apex:tab>

 

and within the controller a simple set and get:

 

public Boolean getAssetClassRenderFlag() {
        return AssetClassRenderFlag;
    }    
    
    public void setAssetClassRenderFlag() {
        setFlagsFalse();
        AssetClassRenderFlag = true;
    }

 

The switchType on the tabPanel is set to client.

 

Hope this helps someone.

 

Andrew

This was selected as the best answer
3333

Hi I am also experiencing this problem. Could you post a full copy of the sample code?