Web Components Community 🔷

Wendy Hsu for FAST

Posted on • Originally published at Medium on

When to use when?

Colleagues having a discussion

Directives are a great way to increase your efficiency when composing templates. But just because they are available, it does not mean they should be used in every scenario. Misusing these can have performance implications and clutter your codebase. In this post, let’s take a closer look at the when directive and compare different conditional cases.

If you are not familiar with FAST directives, take a look here: Using Directives | FAST.

According to the documentation, the when directive enables you to conditionally render blocks of HTML. In other words, it is another way of writing if (condition) { //do something }.

Good use case

This is an example of using if (condition) { //do something } to render our happyTemplate based on the value of the happy property :

With the when directive, we can achieve the same condition check and reduce the if (condition) { //do something } to just one line of code:

Doesn’t this small refactor make you happy?

The when directive is great for the replacement of a single if (condition) { //do something }. The value provided here is making the block of code less verbose.

How about performance? Let’s run some benchmarks comparing these two implementations.

NOTE: All benchmarks are run withfast-benchmarks, and the sample size for each benchmark is 50 with auto-sampling turned on. For a little more context, when we compare 2 versions, a minimum of 100 samples will be run in total. With auto-sampling set at 1 minute, samples will keep increasing until it hits the 1-minute mark.

local version — represents if (condition) { //do something }

master version — represents when directive

benchmark results between if and when for one condition

To summarize the results:

  1. The blue boxes indicate that between the 2 implementations, there was no statistical performance difference in javascript execution time and memory consumption.
  2. The green boxes show that if (condition) { //do something } bundle size turns out to be more than 129.86kb compared to the 129.80kbwhen directive.

These results show that using the when directive here provides better readability and slightly improved bundle size. This is primarily the purpose of the when directive.

Here’s another way you might think to refactor the previous if (condition) { //do something } without the when directive by using the && operator:

This is also a valid and aesthetically pleasing implementation. Let’s run a benchmark to compare this with the when directive implementation:

local version — represents &&
master version - represents when directive

To summarize the results:

  1. The blue boxes indicate that between the 2 implementations, there was no statistical performance difference in javascript execution time and memory consumption.
  2. The green boxes show that if (condition) { //do something } bundle size turns out to be more than 129.82kb compared to the _129.80kb when directive.

Surprise, surprise! when directive is still the winner here in terms of bundle size. When you want to render a template based on a single condition, this nifty when directive is your go-to.

Given these results, the guidance here is to use the when directive to reduce overall bundle size (every byte counts!).

Bad use case 1

While the when directive comes in handy in the previous scenarios, it does not provide optimizations in every scenario.

For example, just as you would not do something like this in your code:

You should not do this with the when directive:

Let’s expand both these implementations and see how they look in the bigger picture, starting with the when directive:

While there are no errors in this implementation, I hope you can see that this can quickly become unmanageable if more conditions are added. Additionally, by separating the two lines of when directive code, it may make it seem like the 2 conditions are not related. This is just an if...else statement, so we should write it as one.

Here’s one way to refactor this with the ternary operator, and eliminating the when directive.

This is arguably more readable than the previous when directive example. Here are the benchmark results between the when_long_example.ts and if_long_example.ts:

NOTE: For this particular benchmark, the click event handler on the button is triggered 10x for each sample taken to switch between templates.

local version — represents ternary operator

master version — represents when directive

To summarize the results:

  1. The blue boxes indicate that between the 2 implementations, there was no statistical performance difference in javascript execution time and memory consumption.
  2. The green boxes show that ternary operator bundle size turns out to be less than 130.82kb compared to the 130.88kbwhen directive.

Given these results, the guidance here is to use the ternary operator to reduce overall bundle size (every byte counts!).

Up to this point, you should get the idea that when directive is valuable as a replacement for if (condition) { //do something }. Outside of this scenario, it is not recommended when working with conditionals or dynamic templates.

Bad use case 2

Let’s look at some more examples to illustrate common misusage of the when directive. Here’s how you might use the when directive to handle templates that change depending on a series of conditions:

If you aren’t careful, you could easily make the error of displaying multiple templates at the same time with the when directive (I made this mistake while drawing up this example).

Let’s summarize what we’re trying to achieve and think about a more effective implementation. Depending on what the emotionalLevel value is, we want to render the corresponding template:

0–1 depressed

2–3 sad

4–5 indifferent

6–8 happy

9–10 ecstatic

With a switch statement you can define the numbers in a specific range, but with the when directive you’d have to be more explicit. Check out the example below using the switch statement:

This implementation is less error-prone and gives better context on how the emotionLevel relates to each of the templates.

Let’s do a quick sanity check with a benchmark run:

NOTE: For this particular benchmark, the click event handler on the button is being triggered 10x for each sample taken to switch between templates. The emotionLevel is incremented from 0–10.

local version — represents switch statement

master version — represents when directive

To summarize the results:

  1. The blue boxes indicate that between the 2 implementations: A. There was no statistical performance difference in javascript execution time. B. Memory consumption was faster with the switch statement compared to the when directive
  2. The green boxes show that switch statement bundle size turns out to be less than130.94kb compared to the 131.01kbwhen directive.

Given these results, the guidance here is to use the switch statement to reduce overall bundle size (every byte counts!) AND memory optimization.

The fun does not have to stop here, you can keep thinking of cleaner ways to refactor your code where it makes sense. For example, if you prefer your template to be less cluttered, you can move the switch statement into its own method and use a map to find the template that matches the condition.

This would undoubtedly result in more code, and running a benchmark confirms that bundle size increases. See below:

NOTE: For this particular benchmark, the click event handler on the button is being triggered 10x for each sample taken to switch between templates. The emotionLevel is incremented from 0–10.

local version — represents map

master version — represents when directive

To summarize the results:

  1. The blue boxes indicate that between the 2 implementations: A. There was no statistical performance difference in javascript execution time. B. Memory consumption was faster with the map solution compared to the when directive
  2. The green boxes show that map bundle size turns out to be more than 131.25kb compared to the 131.01kbwhen directive.

Given these results, the guidance here is to still use the switch statement in the template over the map and when directive solutions if you want both the benefit of smaller bundle size and memory optimization.

While this may not be the most optimized implementation for this particular scenario, if your switch statements become longer, the results could quickly shift to favor the map solution. It’s important to be able to adapt to different scenarios.

In summary, when you are simply working with a single if statement in your template, you should be using the when directive. On the other hand, when you have more complex conditional situations, it is better to omit the use of the when directive !

Performance results can fluctuate depending on how complex your conditionals or templates become. If you keep this in mind, you can continue to improve the codebase you are working on.


Top comments (0)