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.

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.

Before going into the rendering lifecycle on the client, it’s useful to understand the server-side and client-side processing for component requests in brief. The framework builds the component definition and all its dependencies in the server, including definitions for interfaces, controllers, and actions.. 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 used to render the component instance. The client locates the custom renderer in the component bundle or uses the default renderer method.

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");<aura:handler name="init" value="{!this}" action="{!.c.doInit}"/>
    You can customize the init handler and add your own controller logic. For more information, see Invoking Actions on Component Initialization.
  2. render() is called to start component rendering. The renderer for aura:component has a base implementation of render(), but your component can override this method in a custom renderer. For more information, see Client-Side Rendering to the DOM.
  3. 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 inserted 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, for example. Finally, the doneRendering event is fired 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");<!-- The uiExamples:buttonExample container component -->
2<aura:component>
3    <aura:attribute name="num" type="Integer" default="0"/>
4    <ui:button aura:id="button" label="{!v.num}" press="{!c.update}"/>
5</aura:component>
1swfobject.registerObject("clippy.codeblock-2", "9");/** Client-side Controller **/
2({
3    update : function(cmp, evt) {
4        cmp.set("v.num", cmp.get("v.num")+1);
5    }
6})

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. Additionally, HTML tags in the markup are converted to <aura:html> tags.

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

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 ui:myCmp with a ui:button component.Nested components are rendered in a certain order.

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