9

I came across something that vastly improved the performance of the Lightning application that I am building. However, I am not sure exactly why. When my application initializes, I am calling a doInit function that dynamically creates a component and inserts it into the body facet of the application. I am using the following code below:

doInit: function(cmp, event, helper) {
    cmp.set("v.firstLoad", true);
    $A.createComponents([["c:SelfServiceHomeContainer",{attribute:true}],],
        function(newCmp, status){
            if (cmp.isValid() && status === 'SUCCESS') {
                cmp.set("v.body", newCmp); 
            }
        });

The SelfServiceHomeContainer component that I am dynamically creating is a pretty large component with a lot of markup. In my application, I also have a header component that I am directly referencing in the application using the standard <c:cmpHeader /> syntax.

I began noticing that the header component would render instantly once the standard "Loading" dialog disappeared when I would load my Lightning application. However, the body of the application would remain empty for 3-5 seconds before the $A.createComponents() method would complete and insert the newly rendered component. I assumed this was taking longer since this component would need to initialize, run all of its own doInit code and make any necessary asynchronous server calls.

I began reading about the use of the aura:dependency markup when working with dynamically created Lightning components. Therefore, I added <aura:dependency resource="markup://c:*" type="COMPONENT"/> at the application level to allow for creating any of my components dynamically. Now, once the aura "Loading" dialog disappears, the SelfServiceHomContainer component is immediately loaded with the header.

I am also using a similar function to dynamically insert new components into the body based on navbar tab clicks. Before using this aura:dependency markup, I was having to use a spinner because it would take so many seconds to create and render the new dynamic component. Now, when I click a navbar tab, the component loads instantly even though it is being created dynamically. There is no waiting time at all.

I am not sure why referencing all my components as dependencies at the application level that I would pass to $A.createComponents() provided such a significant performance boost. I wanted to see if anyone might have some insight into this?

I also wanted to share what I found for anyone creating components dynamically.

Developer Guide Link

  • I believe it is reducing the number of round-trips to the component server. – Christian Carter Jul 25 '15 at 7:03
10

Lightning (Aura) automatically detects dependencies (components, events, etc) when you reference something in markup (.cmp, .evt, .app, etc) but is blind to dynamic references in JavaScript. The end result is that dependencies that are detected end up with the component definitions (metadata) being included in the highly browser cacheable app.js/app.css resources. When a dynamic reference to something that is unknown client side is encountered Aura automatically faults to the server and calls a metadata service to get the def and then caches is in memory client side. This extra hop can make the first ref significantly more expensive and the fox is to add aura:dependency explicitly in the component that is doing the referencing.

  • Does that mean that dependencies don't require a trip to the component server even on the first rendering? – Daniel Fuller Jul 25 '15 at 13:10
  • Yes, and this makes an important performance impact - also critical for offline/disconnected support. – Doug Chasman Jul 27 '15 at 15:24
  • Oh, great. Thanks, Doug. That is really good to know. – Daniel Fuller Jul 28 '15 at 17:57
  • Doug, just as a follow-up to your answer. What would be the best practice for referencing dependencies in Lightning? Would it be best to declare them at the application level with a wildcard as I mentioned? Or reference only specific components? – Daniel Fuller Aug 3 '15 at 17:41
5

Update as of several releases ago: Lightning/Aura detects a component's dependencies (components, events, interfaces, etc) referenced in markup and in Javascript (when the reference includes the markup:// prefix). When the component is fetched it'll include all of the necessary dependencies automatically. It is no longer required to use <aura:dependency> in the vast majority of cases.

<aura:dependency> should be used only advanced cases where you need explicit control over prefetching of definitions. Using this effectively requires careful consideration and performance analysis. I highly recommend not using them until you have a clear data-based need to control definition prefetching.

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.