Sara Has No Limits

Good Programmers Evaluate, Simplify, Automate and Document

Understanding and Monitoring Visualforce View State

What is View State?

Since HTTP is a stateless protocol, any web application that needs to maintain state between page requests has to deal with how to handle View State. Visualforce handles it by using a hidden form element. Data in components and controllers are stored in an encrypted and hidden field on your page (see image below) that must be serialized and deserialized every time the Visualforce page is requested. Large view state sizes can quickly cause pages to suffer performance problems. Additionally, the Force.com platform limits your pages to a maximum view state size of 135Kb.

Like this Post? Then you will really like the “Improving Visualforce Performance” course that I designed for lynda.com. It was based on this post specifically and goes into great detail about each one of the tips in this post. Check it out!

ViewStatePNG

When is View State needed?

I have seen many examples of code on the forums and in blog posts that use the form tag, even though it is really not needed. I imagine this can happen when people copy code snippets and then change them to fit their needs. Beginning developers will likely not realize the potential negative impact that can occur by leaving in a form tag that is not necessary.

If your Visualforce page includes an <apex:form> component, then it is using View State and could suffer performance problems.

Form tags are only needed when the Visualforce page collects input from the user and is required when using certain apex components such as inputField, commandButton, and any of the action tags. However, it is not needed when just displaying output to users, which many Visualforce pages do. So, the first thing you should always ask is, “Is the form tag in my Visualforce page really needed?” If you are not sure, remove it and try saving the page. If another component requires the form tag, then you will get a compile error telling you this.

How to monitor View State

If your page does require a form tag, then you should be aware of how much view state your page is consuming. To monitor view state, you must first enable this by going to My Settings | Personal | Advanced User Details and clicking Edit. Select the Development Mode AND Show View State in Development Mode checkboxes and click Save.

To access the Development mode footer, navigate to a Visualforce page in your browser by replacing the last characters of the url with /apex/PageName. For example, if you have created a page named AccountSearch and your Salesforce Instance is na3.salesforce.com, then the URL should look like this:

https://na3.salesforce.com/apex/AccountSearch

When you do this, a Development mode footer will appear at the bottom of the page and if your page has a form tag, then a View State tab will appear (such as in the image below).

Transient1

The initial view state (which means that no search has been executed yet) for this particular page is very low – only 2.64KB, which is far below the 135KB threshold allowed. But, what if this page had several more apex components, or what if I executed a search returned hundreds or thousands of records? Well, that number could go up rather quickly and this is why you need to be aware of what your pages view state is and to test it against large quantities of data.

How can I lower View State?

If you do find yourself in the position where your page is performing poorly due to view state (or even encountering limit errors), then there are a few things you can do to fix this. If you have to use a form tag, then the first thing you can do is examine your View State using the Development mode footer and determine whether any of your variables can be marked as transient.

The Transient keyword can be used to flag a variable so that it does not get saved to view state. Chances are, all the variables in your page do not need to be saved between page requests and so this is the easiest and fastest way to lower your view state.

For example, take a look at the markup code below which is used to render a simple Account Search form:

<apex:page standardController="Account" extensions="AccountSearchController">  
  <apex:form >  
      <apex:pageBlock title="Search Result">  
          <apex:pageBlockButtons location="top">
              <apex:inputText value="{!searchstring}" label="Input"/>    
              <apex:commandButton value="Search Accounts" action="{!search}"/>  
          </apex:pageBlockButtons>   
          <apex:pageblockTable value="{!acc}" var="a">  
              <apex:column headerValue="Name">  
                  <apex:outputlink value="/{!a.id}">{!a.Name}</apex:outputlink>  
              </apex:column>  
              <apex:column headerValue="Account Number" value="{!a.AccountNumber}"/>  
              <apex:column headerValue="Industry" value="{!a.Industry}"/>  
              <apex:column headerValue="Phone" value="{!a.Phone}"/>  
              <apex:column headerValue="Website" value="{!a.Website}"/>  
          </apex:pageBlockTable>     
      </apex:pageBlock>    
  </apex:form>  
</apex:page>

and the controller look like this:

public with sharing class AccountSearchController { 
    // Matching Accounts
    public List<Account> acc {get;set;}  
    
    // Search Text entered by user
    public String searchString {get;set;}  
       
    //Constructor
    public AccountSearchController(ApexPages.StandardController controller) {  
    } 
    
    // Action method to search for Accounts  
    public void search() {  
        String searchWord = searchString + '%';  
        acc= [SELECT AccountNumber,Name,Phone,Industry,Website 
              FROM Account 
              WHERE Name like : searchWord];  
    }  
 }

The AccountSearch form is a simple search page that will accept a search string from the user and look for all accounts where the name matches. The results are returned in a variable named acc and the code, as it is now, will store all the records returned in view state. Since this search involves a wild card at the end, if the user looks for all accounts that start with the letter ‘a’ and the org has a lot of accounts, the results could be huge and the view state could easily become too large.

In this example, there are two variables (or properties) that could potentially be marked as Transient: acc and searchString. You can see then both displayed on the View State tab of the Development mode footer (see image below).

Transient

The searchString property is assigned a value when the user enters a word or phrase and clicks Search Accounts. This value is dynamically bound to a SOQL statement and the results are returned to the acc property. Since the searchString value needs to persist between the Get and Post request, it cannot be marked as Transient. But the acc property, which happens to take up the most amount of view state size in KB, contains data results that are just displayed on the page.

Once the results are returned, there is no need to store all the data in view state. The easiest way to reduce view state is to simply add the keyword Transient, so the code for the property declaration now looks like this:

// Matching Accounts
public Transient List acc {get;set;}  

Once the Transient keyword is added, you can save the page and look again at the View State tab. You should see that the acc variable has disappeared entirely and the overall view state size has decreased.

Interested in Learning More?

If you liked this post, then you might be interested in learning more about how you can improve Visualforce Performance by checking out my online course for lynda.com, “Improving Visualforce Performance“. I have an entire chapter dedicated to View State and other chapters involving the following:

  • Evaluating SOQL for efficiency
  • Using Workbench and the Query Plan tool to evaluate queries
  • Reducing use of action tags through Visualforce remoting
  • Working with the StandardSetController class
  • Using static resources

Categories: Visualforce

Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s