Templates vs. macros

When developing the UI of your application in Aria Templates, you might find yourself wondering:  should I use a sub-template or a macro for the display of a certain panel?

This article intends to provide some hints on how to take the right decision, although sometimes it might be a personal choice with no visible consequences.

 

Classes vs. methods

It is useful to think that macros are to templates what methods are to classes in Java. A Template has a much more complex identity and is much more powerful. It has a context which can be decorated with properties and methods, especially by means of a Template Script.

A macro is just a method which should fulfill simple tasks. It receives some parameters and returns some markup. Its context of execution is the same as the one of the template calling it.

 

Code separation and modularity

When you are writing a template, you might be tempted to include a sub-template when

  • your code is getting bigger and bigger and you want to make it more readable by separating it into multiple files.
  • The code you are just about to write for a certain portion of your UI might be shared across different templates.

These circumstances occur often, and of course you are always encouraged to keep your code clean and reusable. Nevertheless, remember that the same purposes can be achieved by using

  • Macro libraries, namely collections of macros.
  • Template inheritance: if multiple templates share the same macros or script methods, you might want to define a common parent and then override it in more specialized templates (but this is out of the scope of this article).

Macro libraries can also have a script in which you can define event handlers and simple functions for data manipulation (of course we are not talking about business logic here, but only about view-related logic). However, as explained later, these scripts do not offer the same capabilities as Template Scripts.

 

Data model

When you include a sub-template you can associate a data model to it. This can be done

  • by providing a static object that will be used inside the sub-template,
  • by associating a module controller to it, that is a sub-module of the current module controller.

The latter option is the most common in complex applications. Templates have access to the data model of the module controller, can call methods declared in its public interface, and listen to the events it raises through the onModuleEvent method defined in template scripts.

It is hence advised to use a sub-template whenever the data it “represents” in the view are managed by a sub-module. From an architectural standpoint, it is advisable that the template hierarchy reflects the separation that has been conceived for the data model and its business logic.

On the other hand, a macro has access to the data that it receives as parameters, but it does not have a data model of its own. It has of course access to the data model of the template calling it.

 

Lifecycle

A template has a lifecycle, and it is possible to define hooks in the template script that are called at different stages of its existence. For example, if you define the $viewReady function in the $prototype of a template script, it will be called when the markup corresponding to the template and its sub-templates has been already appended to the DOM.

A macro is just a method, and as such it does not have any concept of lifecycle attached to it.

 

Performance

Last but not least, some performance considerations have to be taken into account when deciding to use sub-templates. Suppose you are displaying a table in which each row is delegated to a sub-template. If the number of row increases, you might have serious problems when refreshing the whole table, especially in old browsers like Internet Explorer 8 or less.

The richness and power of a template has the drawback of requiring more processing than a simple call to a macro. For example, when a template is refreshed, all instances of its sub-templates are destroyed and recreated. In order to provide an idea, we have created a scenario that allows to compare the refresh cost when using a sub-template or a macro.

Description of the scenario

We have created a very simple template in which, given an integer n,

either we insert n times the following sub-template

{Template {
    $classpath : "my.BasicSubTemplate"
}}

    {macro main()}
        <div>Lorem ipsum dolor sit amet, consectetur</div>
    {/macro}
 
{/Template}

either we call n times the following macro

{macro testBasicMacro()}
    <div>
        <div>Lorem ipsum dolor sit amet, consectetur</div>
    </div>
{/macro}

The generated DOM structure is exactly the same in both cases. The test consists in varying n and performing a certain number of refreshes. The javascript execution times are recorded and averaged. Here are the results in Chrome and Internet Explorer 8.

We remark that the reported results only include the time of javascript execution, so the rendering time, which is highly browser-dependent too, is not taken into account.

As you can see in the above figures, performances are very different for macros and sub-templates, even when the sub-template content is almost negligible.

Of course, figures change a lot in more modern browsers, like Chrome, with respect to older browsers like IE8.

This suggests that sometimes, even if in principle sub-templates are the most adequate choice (for the reasons reported above that transcend performances), it might be impossible to use them for performance reasons: long waiting times are often perceived as bugs and deteriorate the user experience. Moreover, when the number of sub-template increases, you might have alerts from browsers who are dealing with slow scripts.

 

Conclusions

There are many differences between macros and sub-templates, and it is sometimes hard to understand what is the best choice for your use case. A template can interact in various ways with the data model, it allows you to intervene in its lifecycle and it generally corresponds to a reusable piece of UI that takes care of displaying certain data.

However, when the sub-template you want to add appears several times in your page, it might become cumbersome to refresh that page. In that case, replacing the template with a macro is always a good idea. After all, macros can be put in macro libraries and can be given as parameter whatever you need inside of them.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>