Faster Splash Screen

Sometimes one has to make amends for not eating one’s food. I have professed so many times that software should be tested on the lowest available configuration, and I find myself releasing the 260 MB Fonts Manager with the 1700+ Google Fonts inside without having tested on a machine with a hard drive.

Thanks to SSD, launching time was decent, until a tester reported very long launch time. So I booted on the built in hard drive of my 2011 iMac, and sure enough, it takes around a minute or more to launch the app. Quite a dancing number for the icon…

I tried displaying a Modal Dialog in App.Open, as discussed here https://forum.xojo.com/1874-the-easiest-way-i-ve-found-to-make-a-splash-screen/0 but it hardly pops up 6 or 7 seconds before the main window.

It would be largely preferable to have a splash window pop up after 30 seconds max. I don’t know how Xojo does that, but it seems to work that way, even with the ± 1 GB of its executable.

Would it not be great if Mac OS X had the equivalent of iOS launch images ?

I scoured SO, and found a discussion where someone mentions : “the easiest way is to show it in the application delegate’s applicationWillFinishLaunching: method”.
http://stackoverflow.com/questions/685062/how-to-show-a-splash-screen-during-launch-of-a-cocoa-app

It is the first time I see mention of such a method. Would that be possible in Xojo ? Anybody familiar with that delegate ?

Another method I am going to try is to launch a small helper first that only shows the splash window, which contains in its bundle the actual big app and launches it after displaying the splash. Will report of the results.

App.Open event: show the splash window
App.Activate event: lengthy startup code

You need a flag variable in App, so that the startup code in Activate is only executed once.

The way I do it is to subclass Application:

[code]MyApp Inherits App

Property isInitialized As Boolean

Event Open
Event Init
Event Activate

Sub Open()
isInitialized = False
RaiseEvent Open()
End

Sub Activate()
If Not isInitialized Then
isInitialized = True
RaiseEvent Init()
End
RaiseEvent Activate()
End

End[/code]

I just tried a small application whose sole job is to show the splash and launch Fonts Manager which has been copied to its Resources folder within the bundle.

On the iMac 2011 with the built in hard drive, it shows the splash after about 20 seconds, then 20-30 seconds later, the main screen of Fonts Manager. That is not far from most smaller apps.

@Eli Ott : I just tried your method, it gives pretty much the same results. I guess I am going to go for it, as it is way simpler.

Note : I placed Splash.Show in App.Constructor. Just a few milliseconds even before.

Now the splash shows up after 9 seconds, and the main window 10 seconds later.

Thank you.

I still wonder if applicationWillFinishLaunching: would not be even faster to display.

Open event of app:
!. SplashWin.show //I use an NS window, cfr. splash window in MacosLib
2. SplashWin.refresh //from the time of El Capitan the window tends to show up white.
3. Execute the lengthy code.
4. at the end of the lengthy code I close splashWin

In another app I launch the lengthy code from a timer.mode 1 located in SplashWin.

Indeed. I noticed the same. It seems a backdrop shows earlier, though.

About the process I did the same, closing the splash in the Open event of the main window.

Why should it take any time at all? Building the default Desktop project shows its window before the dock icon finishes it’s first bounce. This on a old, hard-drive based computer. Shouldn’t your splash window be able to show as speedily? unless there’s plugins or something that you can’t prevent.

I get some people reporting huge delays on first run…
I unzip files to support folder and I am sure that virus checkers interfere with the speed.

A small desktop project takes 9 MB or so. My app size is now 295 MB. That is far more than the regular 9 MB or so. On an average hard drive, that is more or less the time it takes simply to load the bundle (or copy it from one drive to another).

Unfortunately, execution starts only after the file finished loading. I consider 9 seconds fine in these circumstances.

However, I have been testing extensively on the iMac 2011 hard drive, and indeed, it seems Mac OS X 10.11.4 has a mind of its own, and sometimes takes much longer to start the app. I have noticed up to 30 seconds. No apparent reason.

I also noticed at launch, sometimes it takes up to a minute for El Capitan to show the icons of the desktop. Again, pretty random.

But a bundle on OS X is not loaded entirely. Only the compiled application is loaded. I second Will with his comment “Why should it take any time at all?”.

Are you loading all 1,700 fonts?

If the app is 295Mb, you have a bundle of things in resources, I guess?
Could they be moved out to a separate file?
Installed alongside using an installer?
Bringing your app’s footprint way down, and allowing it to access the external resources when it requires them?

In a desktop app that goes into a tight loop on init, I have a splash window with a textfield that I update whenever an initialization step finishes. I simply split the init steps into several methods and cascade them, which means I call the next at the end of each after setting the tetfield.text using a xojo.core.timer.calllater with a delay of 5. That seems to be enough for the system to update. (But of course doesn’t help if you are in one big loop)

Michel’s question is not about that. His splash screen appears to late, which we don’t understand. It seems that somehow all fonts are loaded ahead of the splash screen appearing.

Oh I see, sorry, I overread that line. Thx, Eli. So it’s an internal resource load that takes that long?

I believe that in 10.11 the first ever run of an app will trigger the signature validation code (which I believe will also show a dialog box from the OS, “Validating application…” - could this be part of the slowdown?

You usually do see a progress bar when the app is validated. I guess it’s rather not the case here.

Yes.

[quote=250587:@Jeff Tullin]If the app is 295Mb, you have a bundle of things in resources, I guess?
Could they be moved out to a separate file?
Installed alongside using an installer?
Bringing your app’s footprint way down, and allowing it to access the external resources when it requires them?[/quote]

This is a Mac App Store app. Everything must be in the bundle. The only alternative would be to download the fonts, but it would take much, much longer.

Apart from the physical need for the OS to actually fill memory with the disk content, files are only registered now in App.Activated. The splash window is loaded in App.Constructor.

At this moment, I guess I am close to the actual time it takes for the OS to transfer data from the hard drive to memory, so I am satisfied. What remains a mystery is why Mac OS X decides sometimes to take two or three times that delay.

If there is no code in the application before the SplashScreen.Show, it will show immediately. What could slow down an application start are external files which have been dragged into the navigator, like icons, picture files, etc. These element are loaded before the App.Open event.

Ahem, make the Splash Screen the Main Window of your app.