Suggestion: better preloader for HTML5 target

Hi!

I’ve seen the custom preloader code and it runs fine. I like the idea of having a custom class called from the project.xml:

<app path="Export" file="GameName" main="MainClass" preloader="Preloader" />

This calls the Preloader.hx class from the Source folder. However, when building for the HTML5 target, I notice there’s a single js game file (for example GameName.js). If the game is huge, this file will be big as well, which means that the preloader will be shown on screen only after this file has fully loaded.

Is there any way to make a separate .js file with just the preloader, so it can start showing faster?

Cheers,
Manuel :smiley:

3 Likes

You’re right – this would be a good idea. For what it is worth, the JS files when served under GZip compression (which most web servers use) is much smaller, but still I agree this would be a logical idea.

In the meantime, it would be possible to preload your project by creating two projects, one to load the other, but there would be some complexities to bear in mind. I’d also like to see an NPM approach for our HTML5 target, so we can get some hot reloading :wink:

As usual, your reply speed is amazing!

It would not worth it for me, there’s a lot of external JS calls, passing the parameters and so on. For now, I’ll just leave it as is. But it would be awesome to implement this in a future update :smiley:

1 Like

I just enabled gzip on my server; actually it was already enabled, but I had to add a .htaccess file in the main game folder. I’ll add it here, maybe it can help someone else. Full content of .htaccess file:

AddOutputFilterByType DEFLATE text/html text/javascript text/plain application/javascript text/css

You’re right, it really makes a huge difference. I’m testing in Chrome with the “Fast 3G” preset, because my regular Internet speed is quite high. Now, even at this slow speed, it takes about 10 seconds for the GameName.js file to load (14% compressed size, ~6.9x times smaller). Good enough for now :slight_smile:

Again, thank you very much for the suggestion <3 It really made my day :smiley:

1 Like

Assets preloading is the big issue with the HTML5 target: preloading everything is counter productive. Is there/could there be a concept of assets “bundles” which you could preload on-demand?

If you have a large JS payload you can look at https://github.com/elsassph/haxe-modular to split it - it’s not possible to split the core Lime/OpenFl library, but it works for the rest of your game/app.

Finally, the best solution is to modify the HTML page to add a static DOM/CSS element indicating that loading is in progress, like a GIF spinner - maybe something to add to the default HTML template?

PS: is the JS minified automatically for a release build?

Yep!

There are a few ways to do this:

Disable Preloading on an Asset

In your XML project, disable preloading for an asset:

<assets path="assets/images" preload="false" />

This means the files will exist at runtime, but will not be preloaded. You cannot use Assets.getBitmapData and other immediate synchronous access to assets, but can use Assets.loadBitmapData and other asynchronous methods instead. If you use the cache = true option (which is the default for these methods), it should be cached to use the get version later.

Disable Preloading on a Library

All assets go into a “default” library, unless otherwise specified. I believe you can even disable preloading of the library and its assets, but be aware that until you have loaded a library, you will need even be able to Assets.loadBitmapData for those assets, as the system will not even know the paths and asset IDs exist yet.

<library name="default" preload="false" />

To load at runtime, you could use something like the following:

Assets.loadLibrary ("default").onComplete (function (library) {
    var bitmapData = library.getBitmapData ("image.png");
    // or
    var bitmapData = Assets.getBitmapData ("default:image.png");
    // or
    var bitmapData = Assets.getBitmapData ("image.png");
    // "default:" prefix is implied, if no library prefix is included
});

Using Additional Asset Libraries

You can easily add assets to libraries other than the “default” library. These are not preloaded by default, unless you add <library name="" preload="true" />

<assets path="assets/other" library="stuff" />

If the asset library is not preloaded automatically, you can use Assets.loadLibrary as above. You can also Assets.unloadLibrary when you are doing using those resources

2 Likes

We minify on release final builds (openfl test html5 -final), but not on ordinary release builds in order to speed up the build

1 Like

I’m under the impression that these answers would be worth going in the documentation:

  • <library> is absent of the XML documentation; this is, IMHO, a major aspect of creating a medium size project; and you better organise your project with that in mind early,
  • -final is listed when running lime help but will be completely overlooked by most people.
1 Like

Hello, I’m trying to use a custom library for the first time, now I have a question. I have the assets of my game in a folder named “media”. In the project xml I have declared this

assets path=“assets/media” rename=“media” preload=“false” embed=“false”

I created a preloader that loads the images as required and everything runs smooth.

Now I want to implement an “avatar selector” in where the user can choose their avatar in between hundreds. So my idea is to download and store that images only at that moment and then release them. As far as I read I should add this on the project

assets path=“assets/media/general/avatares” rename=“avatares” library=“avatares” preload=“false” embed=“false”

I will then preload the images as required ( in pages of 20 images). And once selected I will unload the library.

That should be work ( didn’t test it yet). However I will also require some particular avatars contained there in other places of the code, which uses the first mentioned preloader. The question is, the image is downloaded on “both libraries” or only in one?

What would it happen if

  1. I download the file “avatar50.png” using Assets.loadBitmapData(“media/general/avatares/avatar50.png”, true);

  2. then I call Assets.loadBitmapData(“avatares/avatar50.png”, true); //this should send the file to the “Avatares” lib

  3. I call Assets.unloadLibrary(“avatares”);

  4. Make a call to Assets.getBitmapData(“media/general/avatares/avatar50.png”).

The file was kept on the “default” lib?

I hope the question was clear enough, and thanks in advance for any response it could help.

Found an alternative. I just realize that I can call to Assets.cache.removeBitmapData… Just a suggestion it should be a good idea to have an #alias of a this function as Assets.unloadBitmapData

Regards and thanks anyway
Luis