'Show splash screen only once on app load using angular pwa

I have created a sample splash screen component in my Angular PWA application. I want to show the splash screen only once when the application starts. Right now it is displaying on every refresh on any page inside the app including the starting of my app.

How can I stop load splash screen on every refresh ?

App component:-

<app-splash-screen></app-splash-screen>
<router-outlet></router-outlet>

Splash screen component:-

windowWidth : string | any | number;
  showSplash: boolean = true;

  constructor() { }

  ngOnInit(): void {
    setTimeout(()=> {
      this.windowWidth = +'-' * window.innerWidth + 'px';

      setTimeout(()=> {
        this.showSplash = !this.showSplash
      },500);

    },2000);
  }

Splash screen HTML :-

<div class="app-splash-screen" *ngIf="showSplash" [ngStyle]="{left: windowWidth}">
    <div class="app-splash-screen-inner">
        <div class="app-logo"><mat-icon>eco</mat-icon></div>
        <div class="app=label">Welcome</div>
        <div class="app-loader"></div>
    </div>
</div>


Solution 1:[1]

You can do it by using an option from window object like this:

window.PerformanceNavigationTiming.redirectCount= 0 // not refresh 
window. PerformanceNavigationTiming.redirectCount = 1 // page refresh 

.
.
.
IsRefresh = !!window.performance.navigation.type;

Based on the above condition you can show and hide the splash in the splash component.

Another way of doing this can be by session or local storage, you can create a key like appInit if it exist don't show the splash else show it.

As per request, How can you use session storage. It works per browser tab when user opens a new tab it creates new session and session storage. check here for more details.

When you first time load the app, you can create a session key name isShowSplash. You can do it in splash constructor.

windowWidth : string | any | number;
  showSplash: boolean = true;

  constructor() { 
       // it will be null if it doesn't exist
       const isShowSplash = sessionStorage.getItem('isShowSplash');
       if (isShowSplash) {
           // don't show splash 
           this.showSplash = false;
       } else {
           // show splash 
           this.showSplash = true;
       }
       sessionStorage.setItem('isShowSplash', JSON.stringify(false));
  }

  ngOnInit(): void {
    setTimeout(()=> {
      this.windowWidth = +'-' * window.innerWidth + 'px';

      setTimeout(()=> {
        this.showSplash = !this.showSplash
      },500);

    },2000);
  }

Solution 2:[2]

This component control the show/hide splash screen, the steps will occur like this:

1- the browser will download index.html file in your server, and after will search from files indicate by index.html like: "runtime.js, polyfills.js, main.js, vendor.js" with duration of 300 milliseconds (in my case);

2- After that files download the page will show the splash screen;

3- After all "angular resolver" will make the requests to your server to get your data components;

4- After all images, medias, fonts will be download

5- After, when all download and load, the splash screen will be hide

 @Component({
   selector: 'sei',
   templateUrl: './sei.component.html',
   styleUrls: ['./sei.component.css']
  })   
 export class AppComponent implements OnInit {
   public showSplash: boolean = true; //Show or hide splash screen

   window.onload = (event) => {
     this.showSplash = false; //Trigger when everything load
   }
 }

But we have a problem here, because the "splash screen" only is visible when the angular files is downloaded (index.html, "runtime.js, polyfills.js, main.js, vendor.js") we need wait all this angular files to show the splash screen during app load all components, images, resolver, etc.

We want start "splash screen" when the browser get the first index.html file, at this moment we want start show the splash screen and skill the other angular files.

go to your index.html and below "app" tag you can create your "splash screen", this will show at the moment your browser get angular main index.html file.

 ...
 <body>
   <app></app> //YOUR APP
   <div id="splashScreen">
     splash screen, loading angular, wait... 
   </div>
 </body>
 <style>
  .splashScreenFadeHide{
     opacity: 0; //turn transparent
     transition: opacity 1s linear; //after 1 second
   }
 </style>
 ...

and to hide the splash screen when every thing was load, you will make:

 export class AppComponent implements OnInit {
   ngOnInit(): void {
     window.onload = (event) => { //triger when every thing is load (files, assets, components' resolver, etc)
     
    // All good so add clas "splashScreenFade" to hide the splash screen slowly 
    document.getElementById("splashScreen").classList.add("splashScreenFadeHide")
   }

    //we are listening the "splasn screen" turn transparent and after apply the "display = none"  
   document.getElementById("splashScreen").addEventListener('transitionend', (e) => {
     document.getElementById("splashScreen").style.display = 'none'
   })
  }
}

Now we have a splash screen since the first file is load by browser, and hide only when all files, images, resolver, etc is read.

Give me a like if this help you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2