Reducing Large Internal View State in Visualforce?

Question
I’m building an account search page that allows users to select accounts and pass them to other pages for various actions. However, users are encountering the view state limit. This raises a broader question: what contributes to the internal view state, and how can it be reduced?
I’ve already marked everything transient
where possible. The View State Inspector shows my controller using only 15 KB, but the “Internal” portion of the view state is over 90 KB. The page does not use components, contains only a single form, and references a few other classes. The controller does not store any state that can be regenerated in code upon postback.
Are there strategies to reduce the “Internal” portion of the view state?
Answer:
After investigating, I found that apex:repeat
and apex:outputPanel
contribute significantly to the internal view state. These components internally store a lot of data, leading to excessive view state usage. To verify this, I created a focused example and observed that nearly half of the view state was allocated to “Internal.” Using apex:outputField
could make this even worse.
To mitigate this, I flattened the nested lists into a single list and used a single apex:repeat
to render the UI with simpler markup. This approach retains the original data structure while reducing the internal view state.
Example :
public with sharing class ViewStateTestController {
public List<Row> rows {get;set;}
private static final Integer scaler = 5;
public class Row {
public Boolean isGrouping {get;set;}
public Boolean selected {get;set;}
public String name {get;set;}
public String data1 {get;set;}
public String data2 {get;set;}
public String data3 {get;set;}
public List<Row> children {get;set;}
}
public ViewStateTestController() {
rows = new List<Row>();
for(Integer i=0; i<scaler; i++) {
Row group = new Row();
group.isGrouping = true;
group.Name = 'Group ' + i;
group.children = new List<Row>();
rows.add(group);
for(Integer j=0; j<scaler; j++) {
Row data = new Row();
data.isGrouping = false;
data.Name = 'Data ' + j;
data.data1 = 'Value 1';
data.data2 = 'Value 2';
data.data3 = 'Value 3';
group.children.add(data);
}
}
}
}
Explanation : The ViewStateTestController
class defines a controller with a list of Row
objects, where each Row
can be a grouping or a data entry. The constructor populates this list with scaler
number of groups, each containing scaler
number of data entries. The Row
class has properties for grouping, selection, and multiple data fields, with nested child rows for each group.
The corresponding Visualforce page with nested apex:repeat
:
<apex:page controller="ViewStateTestController">
<apex:form>
<table>
<apex:repeat value="{!rows}" var="row">
<tr>
<td>{!row.Name}</td>
</tr>
<apex:repeat value="{!row.children}" var="child">
<tr>
<td>{!child.Name}</td>
<td>{!child.data1}</td>
<td>{!child.data2}</td>
<td>{!child.data3}</td>
</tr>
</apex:repeat>
</apex:repeat>
</table>
</apex:form>
</apex:page>
Explanation : The code defines a Visualforce page with a form that displays a hierarchical list of rows and their children. It uses nested <apex:repeat>
tags to loop through rows
and their respective children
, displaying each row’s and child’s properties. The inner repeat dynamically creates a table row for each child, showing its Name
, data1
, data2
, and data3
fields.
Optimized Approach:
Flatten the data into a single list with additional attributes to track hierarchy, then render it with a single apex:repeat
.
Updated controller:
public List<ViewRow> viewRows {get;set;}
public class ViewRow {
public Row row {get;set;}
public String name {get;set;}
public Integer level {get;set;}
}
private void flattenRows(List<Row> rows, Integer level) {
for(Row row : rows) {
ViewRow viewRow = new ViewRow();
viewRow.row = row;
viewRow.name = row.isGrouping ? row.Name + ' (' + row.children.size() + ')' : row.Name;
viewRow.level = level;
viewRows.add(viewRow);
if(row.isGrouping) flattenRows(row.children, level + 1);
}
}
public ViewStateTestController() {
rows = new List<Row>();
for(Integer i=0; i<scaler; i++) {
Row group = new Row();
group.isGrouping = true;
group.Name = 'Group ' + i;
group.children = new List<Row>();
rows.add(group);
for(Integer j=0; j<scaler; j++) {
Row data = new Row();
data.isGrouping = false;
data.Name = 'Data ' + j;
group.children.add(data);
}
}
viewRows = new List<ViewRow>();
flattenRows(rows, 1);
}
Explanation : The code defines a controller that flattens a nested list of Row
objects into a single list of ViewRow
objects, preserving the hierarchy using a level
attribute. The flattenRows
method recursively iterates over grouped rows, adding each row’s name and level to the flattened list. This approach reduces the complexity of rendering nested data in Visualforce while maintaining hierarchical relationships.
Updated Visualforce page with a single apex:repeat
:
<apex:page controller="ViewStateTestController">
<apex:form>
<table>
<apex:repeat value="{!viewRows}" var="viewRow">
<tr>
<td style="padding-left:{!viewRow.level * 10}px">{!viewRow.name}</td>
</tr>
</apex:repeat>
</table>
</apex:form>
</apex:page>
Explanation : The Visualforce page uses the apex:repeat
component to iterate over the viewRows
list, which contains flattened row data. For each row, it creates a table row (<tr>
) with a left padding proportional to the row’s level in the hierarchy. The viewRow.name
displays the name, adjusting indentation based on the nesting level to represent the hierarchy visually.
Summing Up
To optimize view state in Visualforce pages, it’s essential to minimize the use of components like apex:repeat
and apex:outputPanel
, which can significantly increase the internal view state due to their data storage mechanisms. By flattening nested data structures into a simpler, single list and rendering them with a single apex:repeat
, you can reduce the view state size. This approach maintains the logical structure of the data while ensuring more efficient rendering, ultimately improving the performance of the page and staying within Salesforce’s view state limits.
Salesforce Training in Chennai: Unlock Your Potential
Elevate your career with our comprehensive Salesforce training in Chennai, designed to equip you with expertise in Admin, Developer, and AI modules. Our program offers unparalleled certification guidance, rigorous interview preparation, and industry-aligned training to ensure you gain a competitive edge. With in-depth modules and expert-led sessions, you’ll build a solid foundation in Salesforce while mastering advanced techniques to meet real-world demands.
Our unique learning approach combines practical hands-on sessions with detailed class notes, enabling you to gain job-ready skills and confidence. Whether you’re starting fresh or upskilling, our training ensures you stand out in the fast-paced Salesforce ecosystem.
Take the first step toward your success by joining our free demo class today and experience the best in Salesforce education!!!
Related Posts :