I have been into the situation when deciding the view architecture. Here are some real figures based on various attributes used with <apex:page>
For example consider a page like this:
<apex:page ~~attribs~~ >
Lot of text
<label> I am </label>
No adding apex tags as they have their on performance.
</apex:page>
Controller is a separate thing (has own processing) so, assume there is no controller in Visualforce page.
1. No attribute
A page with only html tags and no attribute added take around 50ms to load. Consider 50ms
the default loading time of page which has no attribute set explicitly.
2. applyBodyTag attribute
applyBodyTag = false
attribute significantly increases the page loading time as now its browser or the developer's work to apply body tag properly. In comparison to 50ms
it takes around 35ms
.
3. applyHtmlTag and showHeader attribute
This faster than applyBodyTag = false
as no header needs to be rendered by Visualforce engine. In comparison to last 35ms
it takes 9ms
to load a page.
4. applyBodyTag and applyHtmlTag and showHeader attribute
It reduces visualforce engine processing a little. In comparison to 9ms
it takes 7ms
.
5. docType HTML-5.0
This is true HTML-5.0
is faster and in comparison to default (#6) it takes 30ms
.
6. docType default
It is slower than #5. Figure at "#1 No attribute" is similar to this 50ms-58ms
.
7. showHeader attribute
It is faster than showHeader = true
.
8. sidebar attribute
When showHeader is false, sidebar automatically is false. It is faster the true values set.
9 showHeader and sidebar attribute
This is slower than showHeader and sidebar = false
.
10. standardStylesheets attribute
This attribute does not make significant difference, but value = false is faster. Time will be reduces to few ms like if page take 35ms
to load wit will take 32ms
when set to false.
12. showHeader and sidebar attribute but no standardStylesheets
It is same as #10.
Also, longer the html text longer the processing time. More apex tags more processing time. Action functions, Action support, Remoting function and re-render increases page processing time a lot.
As mentioned, describe limits have been removed entirely. Just for completeness, there are a few remaining limits that are affected by these describe calls, but consumption is negligible. These limits are Heap Space
and CPU Time
. The numbers below are for my org, so mileage will vary. I doubt the numbers would ever get high enough to be a concern.
Methodology
You need separate approaches (though one execution is sufficient) to derive the measures that follow. All of this was run in Execute Anonymous
with logging levels set to NONE
except for Apex
, which was at DEBUG
.
Long start = Datetime.now().getTime();
for (Integer i = 0; i < 100; i++)
Map<String, SObjectType> describe = Schema.getGlobalDescribe();
system.debug(Datetime.now().getTime() - start);
// divide above number by 100 (or whatever number of iterations you use) to get ms elapsed
Integer heapBefore = Limits.getHeapSize();
Map<String, SObjectType> describe = Schema.getGlobalDescribe();
system.debug(Limits.getHeapSize() - heapBefore);
// divide the above by Limits.getLimitHeapSize(); for percentage of heap used
Consumption
Schema.getGlobalDescribe()
CPU Time
: ~7ms
Heap Space
: ~0.3%
Schema.SObjectType.getDescribe()
CPU Time
: ~0.002ms
Heap Space
: ~0.001%
Schema.SObjectField.getDescribe()
CPU Time
: ~0.38ms
Heap Space
: ~0.001%
Schema.DescribeSObjectResult.getRecordTypeInfosByName()
CPU Time
: ~0.2ms
Heap Space
: ~0.0001%
Analysis
If you are getting the global describe more than once, cache it. It should be quite simple to cache, and the heap consumption is likely worth the tradeoff even if the number of calls is <50.
For object describes, every 1000 calls (in a single transaction) consume only 2ms (out of 10s), so you don't need to pay much attention unless you are expecting >100K calls. Caching 1000 fields will only consume 1% of your heap space, so that's not a huge concern either. I recommend you use whatever makes your code cleanest.
For field describes, you only get three calls per millisecond, so the calculus is a little different. Now 1000 calls consume an amount of time that is perceptible by humans. However, the cache rate is the same. If you are describing the same field many times, consider caching.
For record type describes, the CPU situation is much the same as with fields. You get five calls per millisecond, so you don't necessarily want to call it thousands of times. But caching it is very inexpensive. You should be able to cache the describes for every single RecordType
without consuming 1% of your heap.
Best Answer
Getting the individual describes is significantly faster. Depending on your situation, it is anywhere from 14 to 850 times as fast!
Describing Many Objects Once
The first continuum I profiled is the situation where you have many objects to describe and make one call to describe all of them.
The individual
getDescribe
approach can describe anywhere from 5 to 11 objects per millisecond, whereas the bulkdescribeSObjects
approach takes anywhere from 2 to 3.5 milliseconds per object. In this continuum, individual describes perform roughly 14 to 30 times better than the bulk describe method.Here is the amount of CPU time consumed for each approach to describe a given number of sObjects once:
Describing One Object Many Times
The second continuum I profiled is the situation where you describe one object many times, for instance if you have describes in a loop somewhere in your code.
The individual
getDescribe
approach can describe an object anywhere from 17 to 33 times per second, whereas the bulkdescribeSObjects
approach takes anywhere from 25 to 29 milliseconds per describe. In this continuum, individual describes perform hundreds of times better than the bulk describe method.Here is the amount of CPU time consumed for each approach to describe one object (
User
) a given number of times: