Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

White screen after splash screen #960

Closed
oliverandersencox opened this issue Nov 6, 2018 · 27 comments
Closed

White screen after splash screen #960

oliverandersencox opened this issue Nov 6, 2018 · 27 comments

Comments

@oliverandersencox
Copy link

oliverandersencox commented Nov 6, 2018

Capacitor displays my custom splash screen as normal, however it will always display a white screen next, before finally navigating to the first route page.
Routing module:
const routes: Routes = [ { path: '', redirectTo: '/welcome', pathMatch: 'full' }, { path: 'app', loadChildren: './pages/tabs/tabs.module#TabsPageModule', canActivate: [AuthGuardService] }, { path: 'welcome', loadChildren: './pages/welcome/welcome.module#WelcomePageModule' }, ]

init function from app.ts

`async initializeApp() {

    this.platform.ready().then(async () => {

      try {

        this.statusBarService.setStatusBar('light');

        SplashScreen.hide();

        console.log('App is ready to go!');

      } catch (error) {
        console.log('Capacitor Warn: Some plugins do not yet have web support');
      }
    });
  }`

It is not a nice look for the app. Is there a particular reason it does this? Maybe something to do with the lazy loading?

@jcesarmobile
Copy link
Member

The splash screen is configured to dismiss after 3 seconds, so it will disappear and show the webview, which might be white depending on the app.

In next release there will be a new configuration option launchAutoHide that you can set to false to not autohide, so you can manually hide it as in your code #956

@oliverandersencox
Copy link
Author

oliverandersencox commented Jan 13, 2020

@jcesarmobile I am still having this issue. My app has this config, yet the white webview always blinks before rendering my initial page. I have created a splash screen page with animation and so this blinking white really ruins the affect!

`{
  "appId": "com.app.ping",
  "appName": "Ping",
  "bundledWebRuntime": false,
  "webDir": "www",
  "server": {
    "allowNavigation": [
      "capacitor://localhost",
      "ionic://localhost",
      "http://localhost",
      "http://localhost:8080",
      "http://localhost:8100"
    ]
  },
  "plugins": {
    "SplashScreen": {
      "launchAutoHide": false,
      "showSpinner": true,
      "androidSplashResourceName": "splash",
      "androidScaleType": "CENTER_CROP",
      "androidSpinnerStyle": "small",
      "iosSpinnerStyle": "small",
      "spinnerColor": "#ffffff",
      "backgroundColor": "#34ace0"
    },
    "PushNotifications": {
      "presentationOptions": [
        "sound"
      ]
    }
  },
  "npmClient": "npm"
}
`

@cepages
Copy link

cepages commented Apr 2, 2020

@oliverandersencox did you fix this problem?

@laumair
Copy link

laumair commented Apr 23, 2020

Facing the same issue.

@oliverandersencox
Copy link
Author

adding "launchShowDuration": 3000 fixed my issue

@ulver2812
Copy link

I had this issue, I tried several configuration with no result.
At the end I used this workaround in app.component.ts to avoid the white screen:

this.platform.ready().then(() => {
      setTimeout(() => {
        SplashScreen.hide();
      }, 2000);
}

@oliverandersencox
Copy link
Author

@ulver2812 I also ended up going with this solution but 500ms works well

@curiouscod3
Copy link

curiouscod3 commented Aug 23, 2020

Doesn't work. still having this issue after splash screen.

@nikunjkakadiya3008
Copy link

still the same issue!! No solution yet?

@ShawinMendis
Copy link

Any updates on this. Still the same issue tried all above solutions :)

@ccasallas
Copy link

I confirm the same issue on vuejs mobile web app.

@JaydipKalkani
Copy link

JaydipKalkani commented Sep 17, 2020

inside capacitor.config.json file, i changed launchShowDuration property value from 0 to 2000 and FadeSplashScreen property value from 'true' to 'false' and it worked. Below is the complete config file.

{
  "appId": "com.your_app",
  "appName": "Your App name",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "www",
  "plugins": {
    "SplashScreen": {
      "launchShowDuration": 2000
    }
  },
  "cordova": {
    "preferences": {
      "AutoHideSplashScreen": "false",
      "ShowSplashScreen": "true",
      "ShowSplashScreenSpinner": "false",
      "ScrollEnabled": "false",
      "android-minSdkVersion": "19",
      "BackupWebStorage": "none",
      "SplashMaintainAspectRatio": "true",
      "FadeSplashScreenDuration": "300",
      "SplashShowOnlyFirstTime": "false",
      "SplashScreen": "screen",
      "SplashScreenDelay": "3000",
      "FadeSplashScreen": "false",
      "AndroidPersistentFileLocation": "Compatibility"
    }
  }
}

@distante
Copy link

distante commented Oct 9, 2020

Is there an official recommendation for this? I just spend 3 hours trying to fix thinking it was an optimization problem on the angular part but no, everything load in the background but after I call hide() a white screen there before the web view is visible.

@tafelnl
Copy link

tafelnl commented Oct 15, 2020

You could at a background to html like this:

html {
  background: #000; /* or any other color */
}

Try to pick a color that is the same as (or close to) your final background color.

This is more of a workaround than a real fix, but at least it is a little better than a bright white flash in my opinion.

@curiouscod3
Copy link

Is there an official recommendation for this? I just spend 3 hours trying to fix thinking it was an optimization problem on the angular part but no, everything load in the background but after I call hide() a white screen there before the web view is visible.

@distante I had spent more than 24 hours for this. Just gave up.. This must be fixed by the core team !!!

@curiouscod3
Copy link

curiouscod3 commented Oct 28, 2020

@jcesarmobile That options don't work for me. I should try 'FadeSplashScreen' option again!

@aparajita
Copy link

What's happening is this:

If you call hide when your app is mounted, at that point the web view is fully loaded, but it has not yet performed the first paint. This can take 100 milliseconds or so, so you end up seeing a blank web view briefly.

The solution to add a short delay (200 milliseconds or so) before actually calling SplashScreen.hide().

// At the point at which your app is fully mounted
setTimeout(() => { Splash.hide(); }, 150);

@distante
Copy link

What's happening is this:

If you call hide when your app is mounted, at that point the web view is fully loaded, but it has not yet performed the first paint. This can take 100 milliseconds or so, so you end up seeing a blank web view briefly.

The solution to add a short delay (200 milliseconds or so) before actually calling SplashScreen.hide().

// At the point at which your app is fully mounted
setTimeout(() => { Splash.hide(); }, 150);

Uhmm, so using like window.load events could help be more precise if the paint takes too long?

@aparajita
Copy link

Good idea! Put this in the main .js file.

document.addEventListener('DOMContentLoaded', async () => {
   const splashscreen = Plugins.SplashScreen as SplashScreenPluginWeb;
   await splashscreen.hide();
});

@aparajita
Copy link

Thanks for the tip @distante, I have added hideOnAppLoaded() to my upcoming splash screen plugin, it does this for you.

@tafelnl
Copy link

tafelnl commented Oct 29, 2020

Only using DOMContentLoaded is still not foolproof and could still result in problems.

The most foolproof way would be the following:

  1. Change the background-color of <html>. See: White screen after splash screen #960 (comment)

  2. Listen to DOMContentLoaded as @aparajita suggested.

  3. Now check if this prevents your app from flickering.

  4. If it does? Nice, you're done. If it does not, you probably have a somewhat heavy app. Read on.

  5. Within the DOMContentLoaded eventlistener, add a setTimeout and just experiment with it, to find a duration that works for you. (Be a little generous. If for example 250ms is perfect for you, use 350ms or so to support low-end devices also)

So in the end you will end up with something like this:

html {
  background: #000; /* or any other color */
}
window.addEventListener('DOMContentLoaded', () => {
  setTimeout(() => {
    SplashScreen.hide({
      fadeOutDuration: 250,
    });
  }, 250); // this could range from 0 to probably no more than 2000, just experiment a little
});

@distante
Copy link

distante commented Oct 29, 2020

What I did was to set an observable in my home page that emits each time my home is checked by angular:

Home Page:

  private componentChecked$$ = new Subject<void>();

  public ngAfterViewChecked(): void {
    this.componentChecked$$.next();
  }

then, I subscribe to it and I wait until it does not emit anything in 100ms (so when it is stable)

  private subscribeToFistEndComponentChecked(): void {
    this.componentChecked$$.pipe(debounceTime(100), first()).subscribe(() => {
      this.globalEvents.emitHomeFinishLoading();
      this.logger.log('End Loading!');
    });
  }

I just hide the splashscreen the first time emitHomeFinishLoading is called. It is not pretty but works all the time. It always wait until the home page is rendered in prod and developer builds for example (with different durations).

As an extra info, I use all my components with changeDetection: ChangeDetectionStrategy.OnPush

@aparajita
Copy link

@tafelnl I went back and read the documentation on the DOMContentLoaded event, it turns out the window 'load' event is a better choice, because that is not fire until all dependent resources have been loaded (e.g. stylesheets and images), whereas DOMContentLoaded is fired when only the DOM has been loaded.

@hyfydistro
Copy link

You can change the color in capacitor.config with backgroundColor.

{
    "appId": "io.ionic.starter",
    "appName": "app",
    "webDir": "build",
    "bundledWebRuntime": false,
    "backgroundColor": "#ff0000" // <-- here
}

You don't need download the extra package "@capacitor/SplashScreen" lol.

Disclaimers: I'm speaking for Capacitor v3 and Ionic v5

@kishan-getstarted
Copy link

I have tried everything its still appears as a white screen can anyone help ?

@stylianosnicoletti
Copy link

Same here using ionic 6, capacitor 3.5.1. Large loading time in white screen on Android after splash screen

@ionitron-bot
Copy link

ionitron-bot bot commented Nov 10, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Nov 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests