6

Not sure if this is a Lightning bug. One of my Lightning pages consume lots of memory (around 4GB) when processing 4000+ records.

I found out that the root cause is : when using component.set to bind the same aura:attribute multiple times, the memory consumption keeps increasing. Garbage collection only happened about few minutes later.

Below is a simple illustration of my testing code (Note: in my actual code, the component.set is called at a separate event when user sorts the table by certain column - the page crashed if a user keeps perform sorting):

var myObjectMap = [];
//Set myObjectMap with 4000+ records based on Apex Controller return
component.set("v.attribute1", myObjectMap); //Consumed 500 MB memory 
component.set("v.attribute1", myObjectMap); //Consumed another 500 MB memory
component.set("v.attribute1", myObjectMap); //Consumed another 500 MB memory 
...
6

This is expected, and part of the reason why Lightning works the way it does. Simply put, anything that is not already a SecureObject is copied into a SecureObject when you use Component#set. You will get much better performance by setting the value to an attribute, then pulling it back out, making any modifications you want, then putting it back in. This makes sure that you have a SecureObject already in memory.

For the record, I tested my paging-sorting-demo by swapping out the value in the controller from 1,000 to 50,000, resulting in 6,711 pages of 10 elements each (~67,110 records, which is simply a multiple of the number of records in my dev org), and noticed about 150kb of allocation per sort using the method of client-side sorting, and I suspect that was only because of the allocation of a new array to display the current page.

In other words, try to make sure you're reusing SecureObject and SecureComponent values when possible, because they won't be re-wrapped each time. This not only saves memory, but also a stupendous amount of processing time, especially on mobile devices. If you're interested, I could probably write up a comparison module to show you the difference in memory usage.

  • Could you please explain in detail of what you mean by make sure you're reusing SecureObject and SecureComponent values when possible? I have gone through your example and I don't see anything related to SecureObject or SecureComponent in the code. I just want to make sure I understand what you are recommending and use it as best practice. Thanks! – javanoob Oct 30 '17 at 0:39
  • 1
    @javanoob the SecureObject is built by Locker Service, not something you invoke manually. When you put an object into an attribute, it is sanitized and placed in a SecureObject. Later, when you get it back out, you still have a SecureObject. When you subsequently put it back in, it won't be sanitized again. – sfdcfox Oct 30 '17 at 3:19
  • I did a simple test and object type is not changed from object to SecureObject. Here is the screenshot: imgur.com/a/wR9YA May be, I am doing something wrong. Sorry if this is a dumb question but I am just trying to understand this concept completely. – javanoob Nov 1 '17 at 18:34
1

I think from a design perspective it does not make sense to have the browser handling 4000 records at a time. Could the Apex controller deliver data to the browser in more manageable chunks?

  • Business does have a strong business case to show 4000+ records at one page. Anyway, let us say even we are going to show a smaller chunk (e.g. 1000 records), this issue still exists - just in a small magnitude – Kaon Z Oct 29 '17 at 0:27
  • 1
    I'm really curious how you are meaningfully putting 4000+ records worth of information onto one visible and usable page at once. If the Lightning component is synthesizing all that data together into some sort of summary view, perhaps that workload can be shifted to Apex. – Charles T Oct 29 '17 at 5:22

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.