3

Components appear to use View State even if they are not rendered.

i.e. there is almost no difference in the View State size between the following two options:

<c:my_component rendered="true"/>
<c:my_component rendered="false"/>

I have a component that conceptually does the following:

<apex:component>
    <apex:attribute name="viewType" description="The view type" type="String" required="true"/>

    <c:my_sub_component_1 rendered="{!viewType='A'}"/>
    <c:my_sub_component_2 rendered="{!viewType='A'||viewType='B'}"/>
    <c:my_sub_component_3 rendered="{!viewType='A'||viewType='C'"/>
    <c:my_sub_component_4 rendered="{!viewType='B'||viewType='c'"/>
    ....
</apex:component>

With the downside that the View State increases from ALL the components, not just the ones that are intended to be shown.

Besides creating a separate parent Component / Page for each of the many combinations, is there any way to completely exclude some sub-components based on the attribute, such that they don't affect the View State size?

  • I actually was unaware that this was a thing. Then again, I've rarely had to deal with state limits from simply creating components. – sfdcfox Sep 7 '17 at 21:54
  • Remember that (as well as controller properties) the view state holds the component tree. So while nothing is generated into the HTML, all the state information that might be needed is still kept. – Keith C Sep 7 '17 at 22:29
3

You could choose to render your page dynamically. It's not normally recommended because... reasons.

Dynamic Visualforce components are not intended to be the primary way to create new Visualforce pages in your organization. Existing Visualforce pages shouldn’t be rewritten in a dynamic manner and, for most use cases, standard Visualforce components are acceptable and preferred. You should only use dynamic Visualforce components when the page must adapt itself to user state or actions in ways that can’t be elegantly coded into static markup.

But, if you need the extra performance, you can do so, it just takes some effort.

<apex:page controller="MyController">
    <apex:repeat value="{!components}" var="component">
        <apex:dynamicComponent componentValue="{!component}"/>
    </apex:repeat>
</apex:page>

public class MyController{
    public ApexPages.Component[] components { get; set; }
    public MyController() {
        components = new ApexPages.Component[0];
        // ... //
        if(viewType == 'a') {
            components.add(new Component.sub_component_1());
        }
        if(viewType == 'a' || viewType == 'b') {
            components.add(new Component.sub_component_2());
        }
        if(viewType == 'a' || viewType == 'c') {
            components.add(new Component.sub_component_3());
        }
        if(viewType == 'b' || viewType == 'c') {
            components.add(new Component.sub_component_4());
        }
    }
}

As always, I recommend reading the manual, because there are some special rules and whatnot, depending on the parameters, etc, but this should get you started.

  • 1
    +1 for read-only UI. In my experience, dynamic input elements are broken as state is lost when errors occur. – Keith C Sep 7 '17 at 22:35
  • @KeithC Yeah, this is a last-resort option. I don't think I've ever had the need to do this, but the tools are there if the need is great enough. – sfdcfox Sep 7 '17 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.