Newer Version Available

This content describes an older version of this product. View Latest

Events Fired During the Rendering Lifecycle

A component is instantiated, rendered, and rerendered during its lifecycle. A component is rerendered only when there’s a programmatic or value change that would require a rerender, such as when a browser event triggers an action that updates its data.

Component Creation

The component lifecycle starts when the client sends an HTTP request to the server and the component configuration data is returned to the client. No server trip is made if the component definition is already on the client from a previous request and the component has no server dependencies.

Let’s look at an app with several nested components. The framework instantiates the app and goes through the children of the v.body facet to create each component, First, it creates the component definition, its entire parent hierarchy, and then creates the facets within those components. The framework also creates any component dependencies on the server, including definitions for attributes, interfaces, controllers, and actions..

The following image lists the order of component creation.

Component definitions and their dependencies are created on the server.

After creating a component instance, the serialized component definitions and instances are sent down to the client. Definitions are cached but not the instance data. The client deserializes the response to create the JavaScript objects or maps, resulting in an instance tree that’s used to render the component instance. When the component tree is ready, the init event is fired for all the components, starting from the children component and finishing in the parent component.

Component Rendering

The following image depicts a typical rendering lifecycle of a component on the client, after the component definitions and instances are deserialized.

The rendering lifecycle starts after the init event and ends with the doneRendering event.

  1. The init event is fired by the component service that constructs the components to signal that initialization has completed.
    1swfobject.registerObject("clippy.codeblock-0", "9");
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17<aura:handler name="init" value="{!this}" action="{!.c.doInit}"/>
    You can customize the init handler and add your own controller logic before the component starts rendering. For more information, see Invoking Actions on Component Initialization.
  2. For each component in the tree, the base implementation of render() or your custom renderer is called to start component rendering. For more information, see Client-Side Rendering to the DOM. Similar to the component creation process, rendering starts at the root component, its children components and their super components, if any, and finally the subchildren components.
  3. Once your components are rendered to the DOM, afterRender() is called to signal that rendering is completed for each of these component definitions. It enables you to interact with the DOM tree after the framework rendering service has created the DOM elements.
  4. To indicate that the client is done waiting for a response to the server request XHR, the doneWaiting event is fired. You can handle this event by adding a handler wired to a client-side controller action.
  5. The framework checks whether any components need to be rerendered and rerenders any “dirtied” components to reflect any updates to attribute values. This rerender check is done even if there’s no dirtied components or values.
  6. Finally, the doneRendering event is fired at the end of the rendering lifecycle.
Let’s see what happens when a ui:button component is returned from the server and any rerendering that occurs when the button is clicked to update its label.
1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!-- The uiExamples:buttonExample container component -->
18<aura:component>
19    <aura:attribute name="num" type="Integer" default="0"/>
20    <ui:button aura:id="button" label="{!v.num}" press="{!c.update}"/>
21</aura:component>
1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/** Client-side Controller **/
18({
19    update : function(cmp, evt) {
20        cmp.set("v.num", cmp.get("v.num")+1);
21    }
22})

It’s helpful to refer to the ui:button source to understand the component definitions to be rendered. For more information, see https://github.com/forcedotcom/aura/blob/master/aura-components/src/main/components/ui/button/button.cmp.

Note

After initialization, render() is called to render ui:button. ui:button doesn’t have a custom renderer, and uses the base implementation of render(). In this example, render() is called eight times in the following order.
Component Description
uiExamples:buttonExample The top-level component that contains the ui:button component
ui:button The ui:button component that’s in the top-level component
aura:html Renders the <button> tag.
aura:if The first aura:if tag in ui:button, which doesn’t render anything since the button contains no image
aura:if The second aura:if tag in ui:button
aura:html The <span> tag for the button label, nested in the <button> tag
aura:expression The v.num expression
aura:expression Empty v.body expression

HTML tags in the markup are converted to aura:html, which has a tag attribute that defines the HTML tag to be generated. When rendering is done, this example calls afterRender() eight times for these component definitions. The doneWaiting event is fired, followed by the doneRendering event.

Clicking the button updates its label, which checks for any “dirtied” components and fires rerender() to rerender these components, followed by the doneRendering event. In this example, rerender() is called eight times. All changed values are stored in a list on the rendering service, resulting in the rerendering of any “dirtied” components.

Firing an event in a custom renderer is not recommended. For more information, see Events Anti-Patterns.

Note

Rendering Nested Components

Let’s say that you have an app myApp.app that contains a component myCmp.cmp with a ui:button component.Nested components are rendered in a certain order.

During initialization, the init() event is fired in this order: ui:button, ui:myCmp, and myApp.app. The doneWaiting event is fired in the same order. Finally, the doneRendering event is also called in the same order.