22

We are having issues with the performance of Javascript Remoting calls. We have been analyzing them using Debug logs and have noticed some things which we hoped someone might be able to shed some light on, or even to confirm if anyone else is seeing these kinds of issues.

1 : Regularly the 'Debug Logs' page shows a request starting at a particular time. However the timestamp of the first log line of the log can be 2 or more seconds later than the listed request start time. It would appear as though the request is blocked/queued up for some period of time. We understand that buffered requests are serialized but we see these delays when there is only a single remoting request underway. Is it possible that our request is being queued for another reason ? Is it possibly being queued by the underlying app server infrastructure ?

2 : The second kind of delay we are seeing in the logs is just as we enter our managed package code. Looking at the example below, the first log line shows the request arriving at 04:53:39.039 and then we see a delay of almost 800 milliseconds before it initializes the handling controller. This feels almost like a remoting endpoint synchronization. Is there any such synchronization/serialization in play here ?

04:53:39.039 (39938000)|CODE_UNIT_STARTED|[EXTERNAL]|XXX|VFRemote: DMAPP.OurController invoke(methodName)

04:53:39.815 (815878000)|METHOD_ENTRY|[1]|XXX|OurController.OurController()*

3: The third kind of delay we see is after the handling controller is intialized. The following log lines show an example of this. The initializer for the handling controller OurController returns at 08:32:28.394 and the next log entry shows some initialization on the first line of the implementing method at 08:32:30.247. From that trace it appears as though the platform runtime spends about 1.8 seconds doing something between initializing the controller and hitting the first line of its implementation. We speculate that this delay is caused by the runtime processing the @RemoteAction annotations in OurController. We have a lot of remote actions in this controller. Is this a contributing factor ?

08:32:28.394 (2394347000)|METHOD_EXIT|[1]|OurController

08:32:30.247 (4247073000)|METHOD_ENTRY|[1]|XXX|DelegateController.DelegateController()

Anyone got any insight / ideas ?

cheers Dave

  • Unfortunately I don't have an answer for you, but I think we're actually seeing the same thing. My first suspicion is that it's large view state serialization/deserialization, but I'm not sure about that. I definitely see the same lag between initiation and invocation that you're seeing, though, so i'm looking forward to seeing what others have to say about this! – Scott Wells Oct 14 '13 at 15:09
  • Can you give an approximation of how many functions/lines the class is? I've always observed Remote Actions to be incredibly fast, but if scalability is a concern, I'd love to be able to replicate this. I've posted a generic answer for now, but I look forward to more information. – sfdcfox Oct 14 '13 at 15:29
  • Thank you for your responses. The controller class is pretty small, in terms of lines of code. However it does have quite a lot of RemoteActions (100+). We have done some refactoring to reduce the number of RemoteActions in play and this has helped with problems of type 3 (but we are restricted in what we can do as the code is in a managed app). We are still seeing type 1 and 2 issues. We have a support case open with Salesforce at the moment and in one of our dev orgs they suggested recompiling all the code which appeared to help things but the response times have since fallen away again. – user4116 Oct 14 '13 at 16:18
  • This is an excellent question, we've had similar experiences with apex execution in general, not necessarily remoting. – Scott Morrison Jul 14 '15 at 16:05
  • Facing same issue....checked with Salesforce...they told @remoteaction is culprit....we are using Angular....not sure what what would be workaround... – Ayub Dec 21 '18 at 13:39
18

JavaScript Remoting does not instantiate the controller or load the view state. For this reason, the methods are declared as static, because there is no instance associated with these calls. There is a buffering mechanism that causes calls that are called close together to be buffered together and submitted at once; this is a default behavior that can be modified per the JavaScript Remoting for Apex Controllers page. Disabling buffering may increase performance, although surely not as much as 2000 ms worth of delay that you're observing. My typical response time when using remoting with buffering is around 19 ms in demo classes I've written.

The server may choose to delay these requests until resources are available, just like any other request. They are not given any special priority queue, nor are they processed any differently than a normal request. They are generally faster, though, because they do not carry their view state with them, which tends to make them faster and more responsive. However, like all software systems, there can sometimes be unforeseen contention. Submitting a case with support may be able to help isolate this problem.

Classes are, as in Java, compiled to bytecode when they are successfully deployed. This means that your code should load in linear time for any given execution cycle. The size of the class and all the classes upon which it depends can play a factor. More importantly, the first run after a class changes may be delayed if there are inter-class relationships that haven't been compiled (e.g. a change to a utility class will cause all classes that use that utility class to have to re-compile on next execution). This delay is usually minor, and should only occur once per code change.

The system also depends on a cache, so loading a controller for the first time in a while (however long the cache keeps recently used bytecode) may result in a loading penalty, but again this is usually far less than your observation of 1800 ms. Generally this delay is less than 100 ms on a busy day, and I can't think of any documented reason why it would take as long as you've observed unless there's some other issue going on, usually internal in nature.

It might be worth the effort to submit a case to Developer Support and see if they can help isolate the issue. Occasionally, there are definitely hiccups in the system, but the engineers usually keep tabs on this and submit hotfixes for situations like this. You might try reducing the complexity of your code and/or splitting your remote functions across multiple classes (this is a great use case for extensions).

1

Though this is an older question I thought I'd add that you may also find reducing the amount of data you send over the wire can significantly improve performance.

For example, after implementing SoC you may find you have a number of remote actions that process the same list of SObject records in different ways. If this is data you've already sent client side then you may be encouraged to just make this list a parameter on your remote action methods and pass the data back from the client when these methods are invoked to avoid redundant SOQL queries.

Depending on the size of the list and the number of fields included in the original SOQL query the remote action method may show significant delays during the deserialization process with this design. In this case it's better to just allow for redundant SOQL queries in your controller and avoid passing the list over the wire.

One approach you may find useful is keeping the list as a parameter and performing a SOQL query only in the event of a null argument. This way you can ensure the best approach is taken by your remote action methods given the current use case.

YMMV, but I've seen significant performance boosts with this design of reducing what is sent over the wire.

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.