Angular 9 Tutorials: Delaying Loading Indicators Using CSS Animations

Angular 9 Tutorials: Delaying Loading Indicators Using CSS Animations

Angular 9.0 Tutorial: In this tutorial experiments with the idea of delaying the rendering of loading indicators using CSS animations in an attempt to decrease the perceived latency by the user in Angular 9.0

I don't really know much about React. And, I certainly know nothing about the upcoming "Suspense" feature. But, from what I've heard various people say on various podcasts, it seems that one of the features provided by Suspense is the ability to delay the rendering of "Loading Indicators" in an attempt to create a better user experience (UX). I am sure there is a lot more to it than what I've picked up; but, based on this superficial understanding, I wanted to see if I could create a similar type of delay using CSS animations in Angular 9.0.0-next.14.

So, from what I think I've heard people discuss, showing a loading indicator can sometimes increase the perception of latency if the latency is relatively low. And, apparently, in low-latency contexts, the user interface will seem faster if you omit the loading indicator altogether and just show a "blank screen" before the content loads.

Honestly, I am not sure how I feel about this. But, I'm not opposed to trying it out for myself. And, it seems that this type of behavior can be easily accomplished with a simple CSS Animation delay. The idea here being that the calling context won't manage the delay - the calling context simply shows and hides the loading indicator the same it would traditionally. The loading indicator would then manage the delay internally using the animatable CSS property, opacity.

Before we look at the loader, though, let's look at the App component. To experiment with this idea, the App component will toggle the display of a "content area" that is delayed by a simulated network request. While the simulated network request is pending, the App component will show a loading indicator, passing-in a [delay] property.

There are several toggle() calls, each of which uses a different [delay] value for the loading indicator. This will help us get a sense of how different delays affect the perception of latency:

// Import the core angular services.
import { Component } from "@angular/core";

// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //

    selector: "app-root",
    styleUrls: [ "./app.component.less" ],
            Toggle Container with delay:
            <a (click)="toggle( 0 )" class="toggle">0ms</a>,
            <a (click)="toggle( 300 )" class="toggle">300ms</a>,
            <a (click)="toggle( 500 )" class="toggle">500ms</a>,
            <a (click)="toggle( 1000 )" class="toggle">1,000ms</a>
        <section *ngIf="isShowingContainer">
                The [delay] property determines the number of MS to wait before the
                loading indicator is renderered. By pushing this logic into the loader,
                it keeps the calling logic simple and binary (ie, show / don't show). The
                underlying THEORY here is that the precense of the loading indicator can
                increase the perceived delay when the latency is relatively low.
            <div *ngIf="( ! isLoading )">
                From the corner of the gym where the BIG men train,<br />
                Through a cloud of chalk and the midst of pain<br />
                Where the big iron rides high and threatens lives,<br />
                Where the noise is made with big forty-fives,<br />
                A deep voice bellowed as he wrapped his knees,<br />
                A very big man with legs like trees.<br />
                Laughing as he snatched another plate from the stack<br />
                Chalking his hands and monstrous back,<br />
                said, "Boy, stop lying and don't say you've forgotten,<br />
                The trouble with you is you ain't been SQUATTIN'."<br />
                &mdash;DALE CLARK, 1983
export class AppComponent {

    public delay: number;
    public isLoading: boolean;
    public isShowingContainer: boolean;

    // I initialize the app component.
    constructor() {

        this.delay = 0;
        this.isLoading = false;
        this.isShowingContainer = false;


    // ---
    // ---

    // I toggle the visibility of the data container, which triggers a "network" request
    // using the given delay for the loading indicator.
    public toggle( newDelay: number ) : void {

        this.delay = newDelay;

        // Toggle the container closed.
        if ( this.isShowingContainer ) {

            this.isShowingContainer = false;
            this.isLoading = false;

        // Toggle the container opened.
        } else {

            this.isShowingContainer = true;
            this.isLoading = true;

                () => {

                    this.isLoading = false;




    // ---
    // ---

    // I simulate a network request with a random amount of latency.
    private getData( maxLatency: number = 1000 ) : Promise<void> {

        var promise = new Promise<void>(
            ( resolve ) => {

                var latency = Math.floor( Math.random() * maxLatency );

                console.log( "Data Fetch Latency:", latency, "ms" );
                setTimeout( resolve, latency );


        return( promise );



As you can see, the presence of the loading indicator is controlled by a simple *ngIf="isLoading" directive. The App component only cares about whether or not the loading indicator is present. It defers all of the "delay" implementation to the loading indicator itself.

So, let's look at the loading indicator component. The component logic is minimal, just showing the text, Loading...:

// Import the core angular services.
import { Component } from "@angular/core";

// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //

    selector: "app-loader",
    inputs: [ "delay" ],
    host: {
        "[]": "delay"
    styleUrls: [ "./loader.component.less" ],
        <div class="indicator">
export class LoaderComponent {

    public delay: number = 0;


For the implementation of this loader, we're going to use CSS animation to delay the rendering of the loader on the screen. Well, to be clear, the loader will be there immediately; however, it will be transparent with an opacity of 0.

Notice that we have the following host binding:

"[]": "delay"

In this implementation, the [delay] input is being parled into a Style property, animation-delay. This is then used in the LESS file to determine when the opacity property gets flipped from 0 to 1:

:host {
    animation-delay: 0ms ; // This will be overridden in the HTML template.
    animation-duration: 250ms ;
    animation-fill-mode: both ;
    animation-name: loader-component-keyframes ;
    display: flex ;

// The opacity property is going to be used to drive the visibility of the loader. It
// will start out as transparent (ie, not visible); and then, the animation-delay
// property defined in the component template (in conjunction with the keyframes) will
// determine how long to wait before the indicator is rendered for the user.
// --
// NOTE: Using animation-fill-mode of "both" causes the 0% state to be applied to the
// component when it is first rendered.
@keyframes loader-component-keyframes {
    0% {
        opacity: 0.0 ;

    100% {
        opacity: 1.0 ;

.indicator {
    flex: 0 0 auto ;
    margin: auto auto auto auto ; // Center vertically and horizontally.

In this case, we're using the animation-fill-mode value of both to indicate that the 0% keyframe should style the component prior to the animation; and, that the 100% keyframe should style the component following the animation. Which means, from the initial rendering though to the animation-delay, the loading indicator will be transparent. And then, once the animation kicks off, the loading indicator will become opaque.

Now, when we run this Angular application in the browser and trying toggling the content area using different delay values, we get the following output:

Angular 9 Tutorials: Delaying Loading Indicators Using CSS Animations

This is not an easy thing to see in an animated GIF. I suggest trying it out for yourself. That said, there may be a bit of sweet-spot, maybe somewhere in the sub-300ms delay range? But, again, I'm not sure how I feel about it. And, I would likely have to see this in action in a robust Angular application before I could really get a sense of whether or not it is worth it. Of course, by encapsulating the delay implementation within the loading component itself, this is something that could be added, removed, or modified in a cross-cutting way once the application has been built.

As a reminder, I know nothing about React Suspense. So, please forgive me if any of understandings here are, in fact, misunderstandings. That said, I am intrigued by the idea of delaying the rendering of a loading indicator in an attempt to decrease the perceived latency by the user. And, I love how easy it is to implement this kind of delay using CSS animations, host properties, and input bindings in Angular 9.0.0-next.14.

View this code in my JavaScript Demos project on GitHub.

via BenNadel

angular angularjs

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Install Angular - Angular Environment Setup Process

Install Angular in easy step by step process. Firstly Install Node.js & npm, then Install Angular CLI, Create workspace and Deploy your App.

Hire AngularJS Developers

Is your business looking for Angularjs developers? At **[]( "")**, our talented developers serve you to get the advantage of advanced features of the AngularJS framework. We offer...

Basics of Angular: Part-1

What is Angular? What it does? How we implement it in a project? So, here are some basics of angular to let you learn more about angular. Angular is a Typesc

AngularJS vs Angular 2 vs Angular 4 - Key Differences Explained

In the case of Angular, various updates have already come within a few years. This blog on AngularJS vs Angular 2 vs Angular 4, will help you learn differences between AngularJS, Angular 2 and Angular 4 on the basis of architecture, language, performance.

Angular vs. AngularJS: Difference between Angular and AngularJS

Angular vs. AngularJS will help you differentiate between TypeScript-based Angular and JavaScript-based AngularJS based on various factors. What is Angularjs? What is Angular? Why compare Angular and AngularJS? Angular vs AngularJS