Closed oliverandersencox closed 6 years ago
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 https://github.com/ionic-team/capacitor/pull/956
@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"
}
`
@oliverandersencox did you fix this problem?
Facing the same issue.
adding "launchShowDuration": 3000 fixed my issue
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);
}
@ulver2812 I also ended up going with this solution but 500ms works well
Doesn't work. still having this issue after splash screen.
still the same issue!! No solution yet?
Any updates on this. Still the same issue tried all above solutions :)
I confirm the same issue on vuejs mobile web app.
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"
}
}
}
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.
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.
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 !!!
@jcesarmobile That options don't work for me. I should try 'FadeSplashScreen' option again!
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);
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?
Good idea! Put this in the main .js file.
document.addEventListener('DOMContentLoaded', async () => {
const splashscreen = Plugins.SplashScreen as SplashScreenPluginWeb;
await splashscreen.hide();
});
Thanks for the tip @distante, I have added hideOnAppLoaded()
to my upcoming splash screen plugin, it does this for you.
Only using DOMContentLoaded
is still not foolproof and could still result in problems.
The most foolproof way would be the following:
Change the background-color
of <html>
. See: https://github.com/ionic-team/capacitor/issues/960#issuecomment-709215809
Listen to DOMContentLoaded
as @aparajita suggested.
Now check if this prevents your app from flickering.
If it does? Nice, you're done. If it does not, you probably have a somewhat heavy app. Read on.
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
});
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
@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.
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
I have tried everything its still appears as a white screen can anyone help ?
Same here using ionic 6, capacitor 3.5.1. Large loading time in white screen on Android after splash screen
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.
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' }, ]
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?