If you are new to Aurelia or perhaps already building something with it, here are some tips and tricks I have learned over the last two years which have helped me write well-performing Aurelia applications.
Keep in mind that Aurelia is like any other framework or library and that it is very easy to write poor performing applications if you’re not careful. Never assume that a framework will stop you from writing bad code.
If vs Show Bindings
In Aurelia there are two attributes: if
and show
which are similar to one another, but have some fundamental differences. The if
binding will add or remove elements from the DOM, whereas the show
binding just applies a conditional display:none
to whatever element the attribute is used on.
Understandably, for some it is confusing. Do you use if
or do you use show
? My rule of thumb is defined by how often I am going to show or hide something in my application.
Am I going to show or hide an element in the page regularly or am I conditionally going to show or hide something sporadically or only just once?
The upside of the if
binding is when the bound value is false, the elements in the DOM will be removed (freeing up DOM space and bindings will be removed). The downside being Aurelia needs to set up a new controller instance and bindings (which isn’t that big of a deal).
I am a huge fan of a light DOM, so I use if.bind
extensively because a large DOM is a lot slower than the time it takes for Aurelia to setup controller instances and bindings. Both have a purpose, it is important to use what works for you.
I do find if.bind
works well for me in most cases, no point having elements around if they’re not being used (in my opinion).
Avoid dirty-checking at all costs
If you’re not sure what dirty-checking is, essentially it’s a timer with a 120-millisecond timeout value that repeatedly loops and checks for changes. You definitely do not want dirty-checking in your application (unless you absolutely need it for some edge case).
If you define a getter in your view-model which accesses one or more values in your class and you do not supply the computedFrom
decorator, it will be dirty-checked.
An example of dirty-checking can be seen below:
export class MyClass {
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
Internally, Aurelia is going to dirty-check this using a setInterval
to constantly poll if the value changes, this is bad. Fortunately, using computedFrom
we can make this an optimised getter which only reacts when one or more dependencies change.
The below example does not use a timer to poll for changes, it makes the getter reactive.
import {computedFrom} from 'aurelia-framework';
export class MyClass {
@computedFrom('firstName', 'lastName')
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
A note on computedFrom: the this
part is implied, so when supply one or more computed values to computedFrom
you are automatically referencing the current class and do not need to supply this
.
A note on computed arrays
the computedFrom
decorator is great for telling Aurelia about your getter dependencies, but it doesn’t work for all values. One such situation is arrays, an array cannot be directly supplied as a getter computed value because it won’t update.
If you’re looking to force a getter to update when an array changes, computed based on its length. When the size of the array changes (items are added or removed) the getter will fire.
import {computedFrom} from 'aurelia-framework';
export class MyClass {
@computedFrom('arr.length')
get firstValue() {
return `${this.arr[0]}`;
}
}
Think big by thinking small
If you come from an MVC background, then you’ve heard the expression, “fat model, skinny controller” and other countless expressions around MVC architecture which have sort-of been carried over into the front-end development jungle.
I prefer fat nothing in my Aurelia applications (or web applications full-stop). If your view-models and/or views are massive, then you have a code architecture problem which is easily solved by reusable components.
A large view-model or view is eventually going to be your undoing (besides the annoying Git conflicts you will encounter working in a team on large files). Large files which do too much are counterproductive and unnecessarily complicated.
If you want to ensure your application is easy to build upon and make it easier for the browser, build tools and test runners to work with your code: break things up into reusable components.
I highly recommend approaching the architecture of your Aurelia applications using the Single responsibility principle.
Use view-cache
This isn’t documented very well, but Aurelia provides a view-cache which can allow you to cache heavy views. This means if you have quite a complex view and you navigate away, but come back to it later Aurelia will use the view-cache and update all of the appropriate bindings.
The benefits are obvious: the whole view doesn’t need to be recreated when you navigate back to it. Just throw view-cache
onto the main opening