I have come across many discussions to improve the performance of Lightning components and everybody has their own approach and solution. What do you reckon is the best way to implement the concept of lazy loading?

  • By adding a timer in controller function to delay component data loading
  • Use AfterRender - This one is quite interesting, and can also achieve the required outcome. However if I have to trigger an event as part of this initialisation, Salesforce discourages to do that, as it results in a chain reaction.

  • Dynamically create component when parent component's initialisation is completed

  • Create/query data when a particular event triggers

IMO, best possible solution would be a combination of above listed items. What do you guys think?

  • I have used counters in the init to determine when everything has been completed. Not sure if that is what you are going for but a property say initDone and a counter to indicate initRunning.
    – Eric
    May 30, 2017 at 5:52
  • I would consider that as part of the 4th option in the question. I would track the change event tied to attribute value and do something when it reaches a specific value. May 30, 2017 at 5:58

2 Answers 2


Don't use timers, afterRender, or dynamic component generation just to try and shave off startup time, because the end result will be longer waits until your application/component is usable. The worse offenders in Lightning are rendering cycles and multiple trips to the server, plus Locker Service, which adds additional overhead.

Lightning is already a lazy-loading framework, by definition. Your initial component graph is calculated, a single request is made to the server to load/cache all of your components, they are then initialized, and then a second rendering cycle occurs when you receive your callback from $A.enqueueAction and you set your attributes. It is true that Lightning needs more optimization, and Salesforce is working on that (e.g. Summer 17 has a number of performance optimizations). Let's look at the options you've presented and see which ones might be useful.


This is not ideal. Either not everything is loaded yet, or you have idle time before your lazy-loading kicks in. Either way, you won't get perfectly optimal experiences on all devices if you pick an arbitrary time to wait before doing stuff. It also virtually guarantees you'll have more rendering cycles than necessary.


Useless for lazy-loading. AfterRender simply tells you the DOM is ready, which is already after a rendering cycle. If you do anything here within the framework, you're going to cause another rendering cycle. Worst case scenario is an infinite loop, best case scenario is additional, unnecessary rendering cycles. AfterRender is a tool for using additional libraries to modify the DOM post-rendering.

Dynamic Component Creation

This has several challenges, the least of which is if you do it wrong, you're introducing additional round trips to the server and additional rendering cycles. Components statically referenced can be loaded during the initial load, reducing server round-trips and possibly rendering cycles. This results in better overall performance in exchange for some additional loading time. The only real benefit you can get out of this is to pre-cache components that you're not using on start-up but that you might need during execution.


This is how Lightning already works, and is intended to be used. You can load data on-demand at the moment the user clicks on a button, link, tab, etc. You should be doing this already. It is not always necessary to load all of the data upfront, and you can usually avoid some of the initial start up time by only loading data that will be initially presented to the user, and then going back to the server to pick up more data, as necessary.

This isn't even always required, as I have written code like this one that loads 1,000 accounts in a small fraction of a second; most of the time spent loading the app is literally just loading Aura/Lightning, not my code or data. Keep in mind that components you don't load upfront will cause a delay in rendering as Lightning has to query the server for components not already in its cache.

Event-driven loading is the preferred way to optimize the experience. It's probably easiest if you simply wall off areas you want to lazy-load with aura:if, then set an attribute when you want to render the area. Typical examples might include additional tabs in a tab panel, or areas hidden until a user clicks on something. You don't need to do anything special, just use aura:if.

Keep in mind that if you need to set a $A.getCallback, you're introducing additional rendering cycles, which is detrimental to performance. Dynamic component generation can be useful to load additional components, but I would avoid doing this for anything that needs to display initially. There is a reason why we have recommendations for placeholders and spinners. It gives the user a sense that something is happening, instead of just a white screen while we wait for things to load.

Part of the user experience is giving the users some sort of indication that the code hasn't crashed, and loading animations helps with that significantly. Other lazy-loading "techniques" are therefore not optimal for this purpose. The entire framework is already in the lazy-loading business, so using additional tricks really should not be necessary in most ordinary cases.

Of course, there are exceptions to the rule, so if you're having a particular challenge, you might experiment with it, but remember that "premature optimization is the root of all evil." Most of the time, there is little that can be done beyond what we're given to work with. You can expect further performance gains in Lightning as the technology matures.


I highly recommend following the Salesforce Developer Blog, particularly the Lightning articles by Christophe Coenraets.

A recent article covered performance and exactly the types of questions you're asking.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .