Why is "internal view state" counted against the developer?

If I have 4k worth of data in the page view state but the VF page structure uses a myriad of nested <apex: tags, such as <apex:repeat /> over map collections of this data in the controller and <apex:outputLabel /> and <apex:inputText /> for data capture and the VF page renderer generates 132k worth of 'internal view state' why is that a problem which is enforced by a limiter?

  1. Why isn't the 135k view state limit measured against user data, which the developer truly has control over? Maybe a 15k user data limit would be more flexible to the developer regardless of the internal view state size.
  2. Is there a black-box setting to allow a page to use more than 135k?
  3. Is there a future config option in the works to allow the developer to specify the limit they would expect to not exceed?

1 Answer 1

  1. The total view state size affects performance; the limit of 135k was chosen as a point where performance is still manageable. While developers have only limited control over the view state size, a large internal state size indicates that the page needs to be optimized by the developer. The view state is sent with every request (except in the new pilot, where the state is stored server side), but more importantly, it has to spend time serializing and deserializing, which is further complicated by the fact that view state is also encrypted.

  2. As far as I'm aware, there's no such feature currently in place. Again, the platform limit is in place to manage performance, not to penalize the developer directly. Once you start creeping past 135kb of state, the system starts to act very sluggishly, even if there are no complex queries involved. It's possible that this may change in the future, but for now, the best choice a developer has is to avoid expensive components as much as possible, and repeat, datatable, and pageblocktable is currently the worst offenders (even more so when using maps and lookups nested inside these structures).

  3. There's no idea specifically for an arbitrary state size increase per developer, which would let them fine tune performance versus functionality, but the there are some ideas on the IdeaExchange about increasing the limit in general (such as to 256k).

That aside, there are things that you can do to minimize view state:

  • Use wrapper classes instead of maps. They are cheaper and hold up well in terms of scaling. You can even use custom getters and setters to internally map wrapper items to a map-- maps are far more efficient in Apex Code.

  • Use Apex Code to formulate expressions whenever possible. {!OR(flag1, flag2, flag3)} is not as efficient as {!flags1_2_3}, where the value is computed in the controller.

  • Avoid repeating tags when possible, especially nested repeating tags. As previously stated, repeating structures are the worst offenders, because each element has to be encoded inside the repeat. This practically limits developers to just a couple hundred iterations per request.

  • Avoid non-transient data. You can often get away with a far smaller view state if you discard information that can be recalculated or reconstructed each page iteration. For example, it's often not necessary to store the results of a query in memory directly-- just the ID values that the query produced. It's fast to query by ID values, because the system is designed to do this.

  • Use remoting whenever possible. The new remoting mechanism lets you render the data client-side, and you can store it all outside the view state. Client-side is the new mantra, and while it has some challenges (such as having a consistent way to use multi-currency formatting), it certainly avoids much of the view state problem.

  • Don't go for "pixel perfect." This was actually in a guide I was reading written by someone at salesforce.com. It's okay to not be "perfectly aligned", if that means you can save view state size/performance. For example, use <a href instead of <apex:outputLink when practical, and use {!Object__c.Field__c} instead of <apex:outputText value= whenever possible. It's even possible to calculate the visibility or editability of fields in Apex Code, and dynamically render those elements to reduce view state size.

  • 1
    With regard to the first bullet: I typically expose Map<Id, ApexClass> or Map<Id, Map<Id, ApexClass>> or Map<Id, Map<Id, List<ApexClass>>> structures directly via controller getter and setter shorthand notation, where ApexClass is an object which has members of its own and may or may not include an sObject reference within it (used with direct bindings in the page). Are you suggesting that the structure exposed directly from the controller class isn't a Map, but instead an instance of a wrapper class with these types of structures within them and it will produce less view state data?
    – Mark Pond
    Commented Nov 5, 2013 at 20:10
  • 3
    Some good advice in this, the key peace for me is avoid repeats with VF components in them. Each VF component uses a lot of internal view state and it stacks up a lot in repeats. I feel the pain with folks wanting to simply use the power of VF but then have to resource to raw HTML elements. If anything Salesforce could review the VF component internal view state and see if it can be reduced. This answer gives further elaboration on the repeat issue and a solution, salesforce.stackexchange.com/questions/4537/… Commented Nov 6, 2013 at 1:52
  • @sfdcfox, amazing answer, the optimization section would be a great addition to this question about how to reduce the internal view state Commented Nov 6, 2013 at 17:56
  • @sfdcfox, amazing answer indeed. Any clarifying information that you can provide on the question I posed earlier about the first bullet point?
    – Mark Pond
    Commented Nov 12, 2013 at 23:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .