Improved Responsiveness for Improved Performance in Angular Apps

Netanel Basal
Netanel Basal
Published in
3 min readFeb 8, 2021

--

When working with responsive applications, it’s often the case that we need to toggle the visibility of some elements in our page, based on the viewport size. The most common technique to do so is to define CSS media queries, and to set the CSS display property to none in the relevant ones. For example:

One disadvantage to this approach is that the element and its children are still part of the Angular render tree, and will therefore be checked each time a change detection cycle runs. This would cause redundant CPU usage and can be noticeable if we have a significant amount of elements and the user browses on a mobile device.

Moreover, Angular would still create the DOM elements, which would redundantly increase the device’s memory consumption.

In addition, our component may need to make HTTP requests or download resources like images or fonts, which would still be downloaded even though the element isn’t visible. This is a waste of the user’s device resources.

Finally, each of the above scenarios would deplete the user’s device battery, and might cause a delay of the First Contentful Paint (FCP).

If you think you a similar scenario on your hands, you can choose a better solution — media queries, but in JavaScript. Luckily, JavaScript comes with a neat API we can use — matchMedia.

Let’s create a structural directive that’ll only create the element for specific viewport size ranges:

First, we define the breakpoints we want to support. You can adjust it to what’s best for your application. Next, we use the matchMedia function to determine if the document matches the media query string we get from our Input, and based on this, we decide if we should create the view. Easy-peasy.

Currently, our code will run only once per directive instance. If we want to make this functionality more dynamic, we can take it one step further, and listen to the viewport’s size changes. First, let’s create a nice observable that wraps the matchMedia change event, and starts with the current value:

Now, we can change our code to listen to those changes:

The Angular CDK also provides breakpointObserver if you prefer to use an existing library that wraps the native matchMedia API.

Finally, if you have an entire module that you don’t want to load on small devices, consider combining this technique with lazy loading:

🚀 In Case You Missed It

Here are a few of my open-source projects:

  • Akita: State Management Tailored-Made for JS Applications
  • Spectator: A Powerful Tool to Simplify Your Angular Tests
  • Transloco: The Internationalization library Angular
  • error-tailer — Seamless form errors for Angular applications
  • Forms Manager: The Foundation for Proper Form Management in Angular
  • Cashew: A flexible and straightforward library that caches HTTP requests
  • Error Tailor — Seamless form errors for Angular applications

And many more!

Follow me on Medium or Twitter to read more about Angular, Akita and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.