2

(I am still new to Lightning so please forgive me if I'm using incorrect terminology.)

I have a lightning application embedded into a VisualForce page. It has two separate components that each calls out to a server when the page loads. Also on one of the lightning components, there are ChartJS charts on there.

Currently, each component on the front end is like this:

  1. query a record in the database
  2. query a remote server to see if record was updated
  3. update the data on the page (charts and all) and on the backend

Whenever the page loads those 2 actions are performed at the same time (I'm assuming that's how Lightning works?)

On the back end, I'm having the apex code call out to the server (I believe you can only call out to servers on apex in Lightning?), do some JSON parsing, and also perform some SOQL queries. But currently, it takes ~6-10 seconds for the page to completely load. The current ideas that I have to speed things up are:

  1. Have 2 separate spinners that load on the page and disappear when all the data gets loaded. This way, it will appear faster to a user.
  2. Separate Javascript call outs? Potentially getting around the $A.enqueueAction() you do when you write callbacks?

Are there tricks that some people are using to speed up the page load? Are there ways to optimize a callout to a remote server in Apex?

Any ideas are greatly appreciated!

EDIT:

I'm pretty sure on the backend I'm not making any nested SOQL statements. I don't have a lazy implementation. Here are the important pieces of the back-end code that makes callout to a remote server:

public static Account getAccount(Id accountId) {
    //make database query for an account using SOQL statement
    return acc;
}
public static String updateAccount(Account acc) {
    //acc is the updated account
    Account accLocal = [SELECT Id FROM Account] //the SOQL query is more complex but it only queries for fields on the account and no references higher
    Map<String, Object> fields = acc.getPopulatedFieldsAsMap();
    //if there were updates, set a flag to true
    if(flag) {
        update accLocal;
    }
}

Here's the front end code for one of the components:

Controller:

({
   init : function(component, event, helper) {
         helper.loadAccount(component);
   }
})

Helper:

({
     loadAccount : function(component, event, helper) {
          var accId = component,get("v.accountId"); //passed into the component
          account = component.get("c.getAccount");
          action.setParams({ "account" : accId });

          action.setCallback(this, function(response) {
        if (response.getState() === "SUCCESS") {
            var account = response.getReturnValue();
            // to speed up display
            component.set("v.serverAccount", account);
            this.getFields(account, component);
        } else if (response.getState() === "ERROR") {
            console.log("Errors in loadAccount", response.getError());
        }
    });
    // Invoke service
    $A.enqueueAction(action);
 },

 getFields : function(account, component){
    var accId = component.get("v.accountId");
    var action = component.get("c.getRemoteData");
    action.setParams({
        //set some parameters here
    });

    action.setCallback(this, function(response) {
        if (response.getState() === "SUCCESS") {
            component.set("v.serverAccount", response.getReturnValue());

        } else {
            throw new Error('An error occured when contacting source. Please try again later.');
        }
        // toggle spinner/ data
        var loadingHeader = component.find("loadingHeader").getElement();
        $A.util.addClass(loadingHeader, "slds-hide");

    });
    $A.enqueueAction(action);
 }

The front-end code for the other component:

Controller:

({
        init : function(component, event, helper) {
                helper.loadDetails(component, event, helper);
        }
})

Helper:

loadGmarDetails : function(component, event, helper) {
    var accId = component.get("v.accountId");
    var action = component.get("c.getDetails"); 
     action.setParams({
        "accountId" : accId
    });
    action.setCallback(this, function(response) {

        if (response.getState() === "SUCCESS") {
            var values = response.getReturnValue();
            var apiResponse = JSON.parse(values);
            var listOfProperties = Object.getOwnPropertyNames(apiResponse);

            var isDataAvailable = listOfProperties.some(function(element, index, array) { 
//toInt is a custom function 
                                                      if(this.toInt(apiResponse[element]) > 0) {
                                                                    return true;
                                                                }

                                                            }, this);
            //display the charts regardless if we get data or not
            component.set("v.apiResponse", apiResponse);
            this.loadCharts(component,helper,apiResponse);
            $A.util.addClass(component.find("spinner").getElement(), "slds-hide");
            if ( !isDataAvailable ) {
                $A.util.removeClass(component.find("noData").getElement(), "slds-hide");
            }          
        } else if (response.getState() === "ERROR") {
            console.log("Error in loadDetails", response.getError());
        }
    });
    // Invoke service
    $A.enqueueAction(action);
}
})
//below is just loading ChartJS with a bunch of data
6
  • 2
    Can you please share your code - client and server sides so we can see if there is something to make better? Also - if code is OK, and the loading time is due to long lists being loaded - you should consider lazy-loading the lists Commented Nov 27, 2016 at 6:05
  • My gut tells me there is something in your db queries that should be improved, as opposed to coming in the javascript. Commented Nov 28, 2016 at 11:15
  • @citizenconn My database queries are pretty normal. No nested SOQL statements or any references to parent. They are just really long.
    – akcorp2003
    Commented Nov 28, 2016 at 16:53
  • @ItaiShmida Lazy-loading is really interesting. However, does Salesforce garbage-collect the object before I can query it again? I think I tried the method before but Apex said I was referencing a null object.
    – akcorp2003
    Commented Nov 28, 2016 at 16:55
  • @akcorp2003 I think you should make your problem more clear - I do not understant exacly what makes the long loading time - are you sure it is the server? how long does it take to load without the server call? can you point us to the specific line or method and it's loading time? Commented Nov 28, 2016 at 21:57

0

You must log in to answer this question.

Browse other questions tagged .