+ Start a Discussion
jhartjhart 

What is going on with Visualforce performance?

Our app uses a number of Visualforce "snippets" that are placed into the page layouts of Contacts, Leads, and Accounts.  These chunks of Visualforce provide related list-like functionality with a couple extra bells and whistles.

 

Lately, our customers have been noticing some severe slowdowns on pages with those Visualforce components.

 

I've also reproduced the issue a number of times myself, both with Debug Logging turned on & with it turned off.

 

For example, I went to view one of the Accounts in our EE org.  The actual queries that the Apex controller is executing should take at most 2 seconds (I've timed this extensively from the command line).

 

However, the first time you try to view an Account, I've seen the page take over one minute to load. I've even seen the whole page *timeout* (after 130 seconds), so nothing (not even the normal stuff, let alone our Visualforce chunk) is visible.

 

Subsequently reloads of the same page take about 5 or 6 seconds - still too long, and still a significant penalty above the raw query time that the Controller needs:

 

 

I have a couple questions:

 

a.  How do the Salesforce Appservers cache Visualforce code?  This pattern seems to me like the individual Appserver that is handling my request has to go get the code for my visualforce page and then compile it, and then cache it, and this causes the periodic huge slowdown.

 

b.  Considering that Visualforce page chunks are embedded in the page layout as an IFRAME, why would they be a gating factor for the rest of the page?

 

 

As far as I can tell, when a browser requests a page that has Visualforce in it, the appserver notices the Visualforce bits and starts running them and *blocks* the entire rest of the page delivery until the Visualforce part is done (and cached, so when the browser actually makes the IFRAME request it gets the answer back quickly).

 

This seems like a premature optimization which is getting an unintended result.  If a small chunk of Visualforce is slow, it ends making the entire page useless rather than simply having a part of the page load a bit slower than the rest. (after the rest is visible & completely useful).

 

Especially when we're seeing these occasional 2 minutes "something's not in cache / gotta compile your page" issues, it makes the use of Visualforce components in standard page layouts a dicey proposition or maybe a bad idea entirely.  Which is especially rough, considering our App has been out for 2 years and hasn't had this problem before.

 

Can anyone at Salesforce comment on this?

Message Edited by jhart on 02-13-2010 10:47 PM
Best Answer chosen by Admin (Salesforce Developers) 
jhartjhart

If anyone else needs the workaround before salesforce (hopefully) addresses this issue:

 

On the page:

 

<!-- workaround to http://is.gd/8lxy1 -->
<apex:form>
<apex:actionFunction name="ajaxSetClientLoaded" action="{!setClientLoaded}" immediate="true" rerender="DeferredLoad"/>
<script type="text/javascript">var cached_onload = window.onload; window.onload = function() { ajaxSetClientLoaded(); if (cached_onload != null) cached_onload(); }</script>

<apex:outputPanel id="DeferredLoad">
<apex:outputPanel rendered="{!NOT(clientLoaded)}">Loading...</apex:outputPanel>
<apex:outputPanel rendered="{!clientLoaded}">
<!-- end workaround -->

... your deferred page contents here ...

</apex:outputPanel>
</apex:outputPanel>
</apex:form>

 

and on the controller:

 

 

boolean clientLoaded = false;
public boolean getClientLoaded() {
return clientLoaded;
}
public PageReference setClientLoaded() {
clientLoaded = true;
return null;
}

 

 

 

 

 

All Answers

jhartjhart

jesse,

 

that is, indeed, a very helpful post.  We'll probably switch to doing it that way (or using AJAX to do the load in the background...).

 

thanks,

john

 

jhartjhart

Jesse,

 

The problem isn't even that we're seeing this:

 

 

 

Instead, we're seeing this:

 

 

At least, that's how firebug shows it (the POST servlet/... to i.na4.... is our snippet, which took about 5 run its queries according to Debug Monitoring, is getting accounted for under the primary "GET" at 6.3 seconds):

 

 

 

But none of this makes sense, as iframes shouldn't even start loading until *after* the parent page is loaded, and nothing about the iframe should prevent the parent page from (a) rendering and (b) becoming interactive.

 

In otherwords, it should look like this:

 




Which is just like your post-workaround flowchart, but without the necessity of the redirect.  This is the bog-standard way that HTML & IFRAMES work; why is salesforce doing it differently?

 

 

When did salesforce start making the parent page wait, server-side, for the child Visualforce page (if that is indeed what's going on ... that's what it *seems* like is going on, both according to what I've observed, plus what firebug shows, plus the fact that the entire page timed out on me when it was really just the embedded vforce bit timing out).

 

 

I don't think it was always like that ... see this video , which was recorded some time ago for a different bug, but which pretty clearly shows the parent loading without waiting for the visualforce stuff to be ready.

 

Any chance salesforce will back out the seemingly-recent "parent page waits for visualforce iframe before rendering" so that visualforce will "lazy load" in the background by default, rather than requiring the (somewhat hackish) redirect on our part?

Message Edited by jhart on 02-13-2010 10:49 PM
jhartjhart

Note: investigating with Chrome's "Developer Tools" feature confirms that the parent page is, in fact, blocking on its child visualforce bits.

 

Is this intentional?  Unless there's some strange javascript interaction causing this, it seems like salesforce is doing a lot of extra work to pre-render & cache the visualforce children on the server.  A lot of extra work which, in the end, is causing the user's experience to be worse.

 

 

Here's an Account detail page with the visualforce removed:

 

 

 

Parent page loads completely in 750ms.

 

 

Here's the same page with a Visualforce subpage that has about 2.5 seconds worth of Apex queries (but apparently takes 4.5 seconds to run & render):

 

 

 

Note, again, it's the parent page that stalls for 5 seconds and the Visualforce bit supposedly loads in 100 ms (clearly b/c its contents have been cached on the server).

 

 

And here's what happens when you have not requested this particular Visualforce snippet from that particular salesforce instance in a day or so ... the entire parent page times out:

 

 

 

Note the visualforce page is never even requested by the browser ... it's the parent page that times out after 2 minutes.

 

 

We're implementing the redirect workaround (5 minutes of work), and we'll be contacting customers to urge them to upgrade (15 minutes of work for each customer, hundreds of customers....).

 

 

It would be simpler for everyone concerned if salesforce would back out whatever change caused the parent page to wait for the visualforce children.  Any chance of that?

jhartjhart

Note - the simplest method of causing redirects (using the "action" property of the apex page tag to return a PageReference for the first request, and null for the 2nd request) doesn't work.

 

Here's the same page with an automatic redirect built in:

 

 

 

I guess we'll need to use a client/javascript based redirect method (or AJAX partial page refreshes).

jhartjhart

If anyone else needs the workaround before salesforce (hopefully) addresses this issue:

 

On the page:

 

<!-- workaround to http://is.gd/8lxy1 -->
<apex:form>
<apex:actionFunction name="ajaxSetClientLoaded" action="{!setClientLoaded}" immediate="true" rerender="DeferredLoad"/>
<script type="text/javascript">var cached_onload = window.onload; window.onload = function() { ajaxSetClientLoaded(); if (cached_onload != null) cached_onload(); }</script>

<apex:outputPanel id="DeferredLoad">
<apex:outputPanel rendered="{!NOT(clientLoaded)}">Loading...</apex:outputPanel>
<apex:outputPanel rendered="{!clientLoaded}">
<!-- end workaround -->

... your deferred page contents here ...

</apex:outputPanel>
</apex:outputPanel>
</apex:form>

 

and on the controller:

 

 

boolean clientLoaded = false;
public boolean getClientLoaded() {
return clientLoaded;
}
public PageReference setClientLoaded() {
clientLoaded = true;
return null;
}

 

 

 

 

 

This was selected as the best answer
stephanstephan

jhart --

 

Thanks for your detailed post on this issue. The behavior you're describing has been around for some time, but there may be some other performance issues that may be exacerabating the situation. I agree that the current "blocking" approach to loading inline VF pages is less than ideal. We're looking into alternatives that might instead load the inline VF pages after the parent page has completed loading.

 

...stephan 

CTU007CTU007

I have similar issues.

 

My tabbed opportunity view page (which overrides the standard view button) is very slow to load --- 27 seconds for me with developer mode on, not sure about other users, but I got complaints.

 

 

My post

Message Edited by CTU007 on 02-17-2010 12:16 PM
jhartjhart

Salesforce, is there any place we can look for a discussion about the current performance issues?

 

I know that, after its initial rollout to NA1,NA6,NA7, the rest of the Spring '10 rollout was postponed due to performance issues (although trust.salesforce.com doesn't mention performance anymore, it did when the delay was first announced).  That implies that Spring '10 has performance problems that must be fixed before the rollout can continue.

 

However, the problems I'm seeing are on Winter '10 instances.

 

From what we've heard from our customers, performance has taken a noticeable downturn over the past couple of months.  We're having a hard time helping our customers understand why there has been a nosedive, because we ourselves don't know.  They keep asking us "what did you do?" ... even though they are still running the same version of our package that they have been for months or even years.

 

paul-lmipaul-lmi
I agree here.  You can definitely see the performance lag if you're stuck ussing the SSL servers instead of the CND-caching ones.  We iframe our Force.com Sites content in a site that only uses SSL, and sometimes, the page load time is horrible, but others, it's near-instant.  SF is definitely hitting some growing pains on this front, regardless of the state of teh Spring release.
jhartjhart

Note -

 

In addition to the Visualforce caching / page loading behavior, there is an actual SOQL bug that is the root cause of the bad performance for us.

 

I've posted about it, and the workaround, here:

 

http://community.salesforce.com/sforce/board/message?board.id=apex&thread.id=27053