5

I need to get the results really fast on my page. I have to decide between 2 approach.

  1. Build a HTTP get service, by using a VisualForce page as Service. Using contentType as 'application/JSON'.

  2. Use ApexController with methods as @RemoteAction.

Which one is faster? Or, is there any other faster way to get data? May be some some architecture is available.

12

@RemoteAction is the fastest you can go without using API calls. If you don't mind using API calls, the AJAX Toolkit is very slightly faster. That said, a well-written RemoteAction can easily run in 1/20th of a second, which is fast enough for most people. Using Visualforce will never be quite as fast, and it's tricky to get back a raw payload without any extra "stuff" stuck on to the end of your response. Also, remote objects are also incredibly fast and reduces the amount of code you write. They're all just about equally fast, so use whatever you feel most comfortable with.


Here's an example with a pretty large payload (100 records worth of data):

Controller

public class RemoteSpeed {
    @RemoteAction public static Account[] accounts() {
        return [SELECt Name FROM Account LIMIT 100];
    }
}

Page

<apex:page controller="RemoteSpeed">
<apex:includeScript value="/soap/ajax/37.0/connection.js" />
<apex:remoteObjects jsNamespace="ro">
    <apex:remoteObjectModel name="Account" fields="Id,Name" />
</apex:remoteObjects>
<script>
function logTime(method, time) {
    var output = document.getElementById("output");
    var row = document.createElement("div");
    var column1 = document.createElement("span");
    var column2 = document.createElement("span");
    var text1 = document.createTextNode(method);
    var text2 = document.createTextNode(time);
    column1.appendChild(text1);
    column2.appendChild(text2);
    row.appendChild(column1);
    row.appendChild(column2);
    output.appendChild(row);
}
function remote1() {
    var time1 = new Date();
    {!$RemoteAction.RemoteSpeed.accounts}(function(data, event) {
        var time2 = new Date();
        logTime("@RemoteAction", time2-time1);
    });
}
sforce.connection.sessionId = "{!$Api.Session_ID}";
function remote2() {
    var time1 = new Date();
    sforce.connection.query("select id, name from account limit 100", { onSuccess: function(data, event) {
        var time2 = new Date();
        logTime("AJAX Toolkit", time2-time1);
    }, onFailure: alert });
}
function remote3() {
    var co = new ro.Account(), time1 = new Date();
    co.retrieve({ limit: 100 }, function(err, records) {
        var time2 = new Date();
        logTime("apex:remoteObjects", time2-time1);
    });
}
</script>
<style>
    #output div span {
        display: inline-block;
        width: 12em;
    }
</style>
<button onclick="remote1()">@RemoteAction</button>
<button onclick="remote2()">AJAX Toolkit</button>
<button onclick="remote3()">apex:remoteObjects</button>
<div id="output">
    <div>
        <span>Method</span>
        <span>Time</span>
    </div>
</div>
</apex:page>

Example output:

Method              Time
@RemoteAction       261
@RemoteAction       175
@RemoteAction       173
@RemoteAction       170
@RemoteAction       125
AJAX Toolkit        228
AJAX Toolkit        300
AJAX Toolkit        148
AJAX Toolkit        117
AJAX Toolkit        133
apex:remoteObjects  215
apex:remoteObjects  262
apex:remoteObjects  191
apex:remoteObjects  194
apex:remoteObjects  194

As you can see, even for 100 records, we're averaging about 1/5th of a second.

While the numbers are kind of all over the place, you'll see that the AJAX toolkit tends to outperform @RemoteAction by about 60ms in the best case, and 80ms compared to remote objects. If you need the small extra boost, the AJAX toolkit is arguably your best choice, as there's less going on under the hood. But you can burn API calls really fast this way.

That said, both RemoteAction and remote objects performed at a rate of about 1/5th of a second, which for that much data is still pretty impressive. Note that all three methods aren't constrained by bandwidth, but rather server performance. These numbers were obtained just now, which is a pretty heavy use time for the server I'm on. If this were the dead of night, I'd expect to see numbers closer to 20-50ms for all three types of requests.

Keep in mind that any of the methods may occasionally experience a hiccup, but in most normal cases, this is about what you can expect.

Also, remember that the RemoteAction methods are buffered, so that time demonstrated includes the buffer time. It's still not that long. You can, however, reduce the amount of time by turning off buffering, if it's really that big of a deal (and in most cases, it's not).

  • That lines up almost exactly with what I suspected, so I'm glad to see my hunches confirmed! Do you have any evidence to make the case more data driven? – Adrian Larson Sep 30 '16 at 14:36
  • 2
    @AdrianLarson I've tested performance like this before. I can write some code or maybe find my old code. Give me a bit, I'll update the answer. – sfdcfox Sep 30 '16 at 14:43
  • 1
    @AdrianLarson I wrote a new page that lets the audience at home play along, and some sample data. – sfdcfox Sep 30 '16 at 15:31
  • 1
    Nice! For those of us who can't average in our heads, @RemoteAction comes in at 180.8, whereas AJAX Toolkit averages 185.2 and in a distant third place, remoteObjects comes in at 211.2. So actually @RemoteAction is fastest on average based on your trials. – Adrian Larson Sep 30 '16 at 15:36
  • 1
    @AdrianLarson And, actually, turning off buffering for the RemoreAction resulted in: 199, 168, 165, 117, and 173, which makes RemoteAction the clear winner at 164.4. – sfdcfox Sep 30 '16 at 15:41

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.