Website freezes during PlayCanvas assets loading

Hi again,
The game I’m working on will be part of a website. When the website is opened the PlayCanvas game should load the needed assets in the background. Once done, the game will be available for playing.
During this loading the website should be responsive.

I use the code below to load some of the assets. The problem is that during this loading the complete webpage freezes. As soon as the asset is loaded it response normally. What can I do about that?
Isn’t the idea behind this callback structure that the event loop of the website keeps running?

    const url = "./assets/models/ship/Ship_2K_Compressed.glb";
    app.assets.loadFromUrl(url, "container", function (err, asset) {
        // create an instance using render component
        const entity = asset.resource.instantiateRenderEntity({
            castShadows: true,
        });
        console.log("Starting ...");

        app.root.addChild(entity);
        entity.setPosition(0, 5, 0);
        entity.rotate(0, 0, -22);
        entity.rotate(0, -45, 0);
        entity.render.renderStyle = pc.RENDERSTYLE_WIREFRAME;

        //entity.setLocalScale(20, 20, 20);

        app.on("update", function (dt) {
            if (entity) {
                //entity.rotate(0, -20 * dt, 0);
            }
        });

        app.start();
    });

It shouldn’t freeze during loading. There may be a few frame drops when the entity is added to the scene as the shaders need to be compiled on first render.

Could you please profile this using Chrome dev tools to see what is taking the time during the problem time? During the loading, some GPU resources are allocated, for example Vertex and Index buffer, and for larger models this could take some time. Or maybe something else, but profiling should be able to find out what it is.

Yet another new thing to learn for me. Exiting times!

Do I interpret correctly when saying that the function LoadFromUrlAndFilename is holding up the initialization for severval seconds? That seems not strange to me. But why is the website not responsive during this time?

It should not, no. It sends off an async HTML request for the file and when it has finished downloading, it gets added to the asset registry and the callback is called.

It shouldn’t which is odd. If you can spin up a codepen or example that replicates the issue, that would really help.

Actually, the engine-only examples have the same problem.
The AREA LIGHTS example for instance takes some time to load. And during that load, you can not resize the window. The app is freezed.

The area lights are a bit of an exception as its due to shaders being compiled and there’s a known issue with Windows Chrome and DirectX that we are investigating.

If you can spin up an example on codepen or github, that will hlep us investigate. Right now, it’s really hard to help without seeing an example that showcases the issue for you.

It is very difficult for me to create a simple codepen or Github example because currently it is very interwinded with a website we are building. But if that is the only way to solve this issue, I will try to do so.

But I found an other example that demonstrates this issue of which you will have the code too: the ASSET VIEWER example: PlayCanvas Examples

When starting this example, the app gets inresponsive for a long time. Even after starting and clicking the Next or Previous buttons for the first time, some processing is done and during that time the app gets inresponsive too.

We will have to load a lot of assets when opening our webpage. It would be unacceptable if the website will be inresponsive for such a long time.

In that demo of the asset viewer, you can see the freeze only happens when the models, materials are added to the scene, not during the downloading

(see the mouse over highlights on the buttons stop working in that frame)

And from the profiler, as we mentioned before, this is due to the shader compilation of the materials

You can migrate this through a variety of ways depending on what you are looking to achieve and what you are rendering.

Use simpler materials. The more channels you are using (eg clear coat, ambient occlusion etc), the more expensive the shader is going to be to compile.

Take the compile frame hit all at once. Rather than loading all GLBs and adding them to the scene as soon as they are downloaded, download all the data first and the add them to the scene all in the same frame. The total time is not reduced but it becomes just one time issue.

Iframe the PlayCanvas app from the main page. That way it only locks up the iframe and not the main page.

Load/add models when you need them rather than at the start. If you can lazy load and add the models when you need them.

There are some known issues with Windows DirectX and shader compilation with clustered lighting that causes very long compile shader times.

To reduce this, there are few things you can try:

If you are only using a few omni and spotlights that don’t change, try disabling clustered lighting altogether.

If you need clustered lighting but don’t need the shadows, disable shadows in the clustered lighting params: Scene | PlayCanvas API Reference. Even if you must have shadows, consider disabling it for clustered lighting and use a directional light for shadows instead.

If you can provide a video of what you are seeing as ‘freezes’, that would help us a lot too