[SalesForce] Display lighting:spinner component during component render cycle

Examples of lightning:spinner usage that I've seen are used for delays in controller logic processing, ie waiting on an asynchronous callout. But what I'm trying to solve for is being able to show the spinner while the actual component markup is rendering.

For example, I have a child component that builds a complex table using nested aura:iteration and aura:if tags, and takes 5-10 seconds for the actual table to be rendered on the page, while the controller logic completes instantly.

I can't figure out how to turn on the spinner at the beginning of the render process, then turn it off after.

My attempt

I tried using two standard event handlers for init and render, which I understood to be fired on either end of the rendering process. I paired lightning:spinner with an <aura:if isTrue="{!v.showSpinner}">, then in each of those handler methods I set showSpinner to true and false, respectively.

component:

<aura:attribute name="showSpinner" type="Boolean" default="true"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>

 <aura:if isTrue="{!v.showSpinner}">
    <lightning:spinner variant="brand" alternativeText="Page loading..." aura:id="loadingSpinner"/>
</aura:if>

controller:

doInit: function (component, event, helper) {
    console.log('doinit fired');
    component.set("v.showSpinner", true);
},

onRender: function(component, event, helper){
    console.log('onRender fired');
    component.set("v.showSpinner", false);
},

Outcome

Visually: About 5 seconds pass before the page finishes rendering (during which the SF page framework displays, including the parent lightning component, but the table inside the child component does not), then the table appears. The spinner does not show at all.

Console Log:
I expected that onRender wouldn't fire till after the table was displaying, but apparently not, because immediately upon component creation and prior to the table displaying, the following console log lines displayed:

doinit fired 
onRender fired  
onRender fired

Then, immediately after the table finished rendering, onRender fired three more times.

So that explains why the spinner doesn't show. The first onRender fires instantly, turning off the spinner.

What I don't get is why onRender is firing five times during the initial rendering of the table, when the data object that populates the table hasn't been manipulated by code or user entry yet.

How can I ensure that the spinner isn't hidden until after the table component truly finishes rendering? is there a an event other than init that flags the start of any individual render process, since there are clearly several rerenderings on the initial page load?

Best Answer

Using a window.setTimeout() worked for me.

helper.displaySpinner();

window.setTimeout($A.getCallback(function(){
    // Your async code here
    helper.hideSpinner();
}), 1);
Related Topic