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

Godot HTML5 games have a really long time to first interaction #41118

Open
Zireael07 opened this issue Aug 8, 2020 · 23 comments
Open

Godot HTML5 games have a really long time to first interaction #41118

Zireael07 opened this issue Aug 8, 2020 · 23 comments

Comments

@Zireael07
Copy link
Contributor

Zireael07 commented Aug 8, 2020

Godot version:
Varies (see below)

OS/device including version:
Computer: Linux Manjaro, Intel HD Kaby Lake (UHD Graphics 620), Brave browser (so Chromium-based)
Mobile: LG K61, Chrome
both tested on the same, an LTE (!) connection

Issue description:
Godot HTML5 games have a very long time to first interaction (what is called TTI in web development jargon)
As I couldn't inject any sort of a time() call into already released projects, I used a stopwatch on my mobile to time the computer and a stopwatch website to time the mobile.

  1. Tanks of Freedom
    Computer: ~31 seconds
    Mobile: 1 min 31 seconds
    (I counted the time to the start of the in-game splash screen, not to main menu)

  2. Faless's textedit demo
    Computer: ~10 seconds
    Mobile: ~34 seconds

Steps to reproduce:
Follow the links, get a stopwatch ready...

Minimal reproduction project:
Faless's textedit demo probably qualifies? Note that it uses GLES2, which is recommended for web/mobile, AND is just two controls slapped on...

cc'ing @Faless

@Calinou
Copy link
Member

Calinou commented Aug 8, 2020

This is probably due to the large WebAssembly payload. I doubt much can be done about it unless you specifically build an HTML5 export template that disables all the modules you don't need.

Also, make sure to upload your project on a website that supports gzip compression such as GitHub Pages. Most notably, itch.io doesn't support this as they let the engine itself do it (like Unity). However, this approach is less efficient. Unfortunately, there's no way for you to enable it on a per-project basis 🙁

Give GDScript Online a try. It applies all of the advice outlined above.

@Zireael07
Copy link
Contributor Author

The time I counted is both the time it takes for anything vaguely relevant to show up (the loading spinner) and the loading bar/loading text depending on Godot version used. I am not too sure what the difference between the two is (is one the initial payload and the other loading assets/pck?)
BTW the spinner is fairly slow to spin on mobile, leading to impression that the page hanged up.

This is probably due to the large WebAssembly payload. I doubt much can be done about it unless you specifically build an HTML5 export template that disables all the modules you don't need.

Would it be possible to get a "2D" switch in the export window, that would disable 3D modules? I suspect this is unnecessarily bloating many 2D projects (which I expect the majority of web exports to be)

A more involved fix would be to move away from Emscripten in favor of e.g. https://github.com/schellingb/ZillaLib (Zlib license ought to be compatible), except we'd need to add fake filesystem support to it (I believe we are not using any more Emscripten features such as threads...?)

@Zireael07
Copy link
Contributor Author

Just for reference:
GDScript online: 7 seconds on computer, 20 seconds on mobile
Looks like gzip compression does indeed shave off a bit.

@Calinou
Copy link
Member

Calinou commented Aug 8, 2020

Would it be possible to get a "2D" switch in the export window, that would disable 3D modules? I suspect this is unnecessarily bloating many 2D projects (which I expect the majority of web exports to be)

This is feasible, but we'd have to compile 2D-only export templates in addition to the current ones. This would make export template TPZ archives significantly larger (600-700 MB).

@Zireael07
Copy link
Contributor Author

What happened to the idea of being able to download only those export templates that you are interested in (e.g. only Windows, only web)?

@Calinou
Copy link
Member

Calinou commented Aug 8, 2020

@Zireael07 This was requested in godotengine/godot-proposals#647, but keep in mind adding more export templates may require designing a more complex GUI for that feature.

That said, we could display only one button per platform and include both 2D and 2D + 3D export templates in the same TPZ. This is probably fine since most people will only download 3-4 platforms at most.

@Zireael07
Copy link
Contributor Author

I expect web is the platform that needs 3D excluded the most, desktop doesn't suffer visibly from the added bloat. And putting both versions in the same tpz would be fine, too.

@mindinsomnia
Copy link

Would it be possible for Godot to automatically cull modules during export that aren't used?

@Calinou
Copy link
Member

Calinou commented Aug 8, 2020

@mindinsomnia That would require a compiler toolchain to be present, in addition to being able to compile for the target platform from the OS the editor is currently running on. Unfortunately, both of these are far to be guaranteed, so I don't think it's an idea worth pursuing.

See also godotengine/godot-proposals#1001.

@Zireael07
Copy link
Contributor Author

Most notably, itch.io doesn't support this as they let the engine itself do it (like Unity). However, this approach is less efficient.

Could Godot then handle it somehow? I imagine gzip doesn't do much for pck, which is already zipped, but it could help with the wasm payload...

@Calinou
Copy link
Member

Calinou commented Aug 9, 2020

I imagine gzip doesn't do much for pck, which is already zipped

gzip or Brotli will help significantly for most PCK files, as a PCK isn't compressed. (PCK files can contain compressed data, but they can and will often contain uncompressed data as well.)

Could Godot then handle it somehow?

This was requested here already: #20996

@Zireael07
Copy link
Contributor Author

Zireael07 commented Aug 15, 2020

One more thing I just realized: most Emscripten projects use a loading bar where Godot has a spinner (because the latter Loading... or loading bar is clearly Godot's)

Examples: https://marukrap.github.io/RoguelikeTutorial2020/Demos/Part10.html
https://personal-1094.web.app/gemrb.html (this is Baldur's Gate 2 running in GemRB on Emscripten - I haven't timed the loading but it's fairly fast for such a large game)
EDIT: Baldur's Gate 2 TTI is 24s on desktop. So a huge AAA 2d RPG game loads faster than Tanks of Freedom...

A loading bar would make it clearer to the user that the page hasn't hanged...

@Calinou
Copy link
Member

Calinou commented Aug 15, 2020

@Zireael07 Godot uses both a loading bar and a spinner depending on the loading state. When downloading the PCK, a loading bar is displayed. When initializing the engine, a spinner is displayed.

We can only display a loading bar if we can know the loading percentage.

@Zireael07
Copy link
Contributor Author

@Calinou: As the linked sites show, Emscripten projects show a loading bar when initializing the project. (It literally shows 'initializing' in marukrap's demo) It seems to work both for toy demos and for big projects.

@Faless
Copy link
Collaborator

Faless commented Oct 6, 2020

I'll chime in with a couple of remarks:

  • The Tank of Freedom version linked above do not use WASM, but ASM.js (godot 2.1?), which produces slower, and bigger output size (more than double).
  • Baldur's Gate 2 is a AAA game from the year 2000 (total size is <90 MiB, although still more than tank of freedom, agreed). And the code base of the 2 engines are clearly not comparable.
  • @Zireael07 Can you try comparing it with this version?. A regular 3.2 WASM build (but with LTO enabled), and served with compression, although my server has a 100 MiB/s connection, so it might be a bottleneck for you).

Further improvements might include fixes to properly support streaming instantiation of WASM in browsers that supports it (emscripten do it by default, but our custom code that shows the loading bar overrides it for now).

@Zireael07
Copy link
Contributor Author

@Faless: The linked version above takes around 11s from click on the link to splash screen (computer).

Haven't tried mobile yet, but I expect it'll be similar to the results from the text edit demo. 10s on computer and 30s on mobile seem to be the lower bound, and neither looks good for a prospective Godot user who wants to target HTML5 (Tanks of Freedom is a small game, nowhere close to an enormous game like Baldur's Gate 2 in terms of hours of content inside or assets...)

@akien-mga
Copy link
Member

akien-mga commented Oct 9, 2020

Can you try comparing it with this version?. A regular 3.2 WASM build (but with LTO enabled), and served with compression, although my server has a 100 MiB/s connection, so it might be a bottleneck for you).

For me this version loads in ~4 seconds on desktop (Linux, Firefox Nightly) and ~6 seconds on mobile (Android, Firefox Beta) (counting from entering the URL, so includes download time). That's pretty good, most big websites nowadays take the same time to load.

@Faless
Copy link
Collaborator

Faless commented Oct 9, 2020

Haven't tried mobile yet, but I expect it'll be similar to the results from the text edit demo. 10s on computer and 30s on mobile seem to be the lower bound,

I'm seeing ~11 sec loading time on my phone (Xiaomi Mi A3, Firefox).

Tanks of Freedom is a small game, nowhere close to an enormous game like Baldur's Gate 2 in terms of hours of content inside or assets...

Yeah, but this has very little to do with initial load times, most of the time is due to WASM loading/instantiation (beside the download of the assets, which is already done in parallel).

@Zireael07
Copy link
Contributor Author

Hm, you guys are testing with cache cleared? I do (to make sure we're not seeing fast times due to reusing cache) - if you do too, maybe it's a matter of the browser (Chrome vs Firefox)

@Faless
Copy link
Collaborator

Faless commented Oct 10, 2020

Hm, you guys are testing with cache cleared?

Yes, and the cache won't affect timing beside the download time unless you are on a poor connection (12 MiB engine + 12 MiB assets = 24 MiB, but the engine is served compressed < 4 MiB so it's a total of 16 MiB which is ~7 seconds on a poor DSL connection and <2 sec on a regular 100 Mib/s). (I hope I did my maths correctly).

I gave Chrome a try, I get the same result on Linux (actually, slightly better then FF), While on mobile it's a bit slower (~15 secs).

I guess the difference is in phone/PC performances?
Anyway, would be nice if you could try that version on mobile too so we have actual data.
Can you also provide the specs of your PC? And maybe try with FF or Chrome? (not sure which version of chromium brave uses, and if they have some custom patches that might affect performances).

@slabgames
Copy link

Hi, thanks for replacing XHR with Fetch. But it also breaks my code to preload gzipped file using this script
https://gist.github.com/natrim/1a19f4b7668e0474897f3f28171f3b33

Is there a way to get this to work with Fetch?

@Calinou
Copy link
Member

Calinou commented Mar 30, 2021

@slabgames Can't you rely on the web server serving precompressed files instead? This way, you can also use Brotli compression (even if the web server doesn't support it).

Here's an example for Apache: https://gist.github.com/Calinou/fc0fe1003c95380054f0084f9476e476

@slabgames
Copy link

@Calinou Thanks for answering. I'm afraid I can't do server side compression, since I'm not going to serve the game on my own server. That's why I try to find a way to do it on client side

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants