defold
defold copied to clipboard
HTML5: improve game loading time by downloading engine + data in parallel
Is your feature request related to a problem? Please describe (REQUIRED): Now, Defold loads a game built for HTML5 in the following sequence:
- The page loads
dmloader.js. - Then, it loads the engine, i.e.
dmengine.wasm+_wasm.jsor_asmjs.jsfiles. - Initializes the engine.
- Then, finally, starts loading the data. It does that concurrently and that's great!
- Runs the game.
Describe the solution you'd like (REQUIRED): I see no reason to not to load the engine and data files in parallel and then start the game, i.e. the sequence could be:
- Load
dmloader.js. - Then, load the engine and the data in parallel.
- Initialize the engine and run the game.
And, if you are going to do something with the HTML5 loader, then please also take a look at issue 7039.
I experimented with work-arounds for this issue using link rel="preload" tags.
The measurements indicate @aglitchman 's suggested sequence is the most optimal solution.
Methodology
I used a relatively small HTML5 build (3MBs total for all assets). I also used simulated "Fast 3G" speed throttling in Chrome devtools. Your results may vary for your own build and network speed.
Findings
Baseline: no preloading
- Largest Contentful Paint: 1.3s (seconds)
- All assets loaded: 23s
Preloading all assets
- Largest Contentful Paint: 2.5s (+92%)
- All assets loaded: 18s (-22%)
<link rel="preload" href="dmloader.js" as="script" />
<link rel="preload" href="game.wasm" as="fetch" crossorigin="*" />
<link rel="preload" href="game_wasm.js" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/archive_files.json" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/game.arcd0" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/game.arci0" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/game.dmanifest0" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/game.projectc0" as="fetch" crossorigin="*" />
<link rel="preload" href="archive/game.public.der0" as="fetch" crossorigin="*" />
Preloading dmloader.js, then everything else
- Largest Contentful Paint: 1.3s (no change)
- All assets loaded: 19s (-17%)
<link rel="preload" href="dmloader.js" as="script"
onload="document.querySelectorAll('link[data-rel]').forEach(link => link.setAttribute('rel', link.getAttribute('data-rel')))" />
<!-- The following links have been rendered inert until the above onload event fires -->
<link data-rel="preload" href="game.wasm" as="fetch" crossorigin="*" />
<link data-rel="preload" href="game_wasm.js" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/archive_files.json" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/game.arcd0" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/game.arci0" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/game.dmanifest0" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/game.projectc0" as="fetch" crossorigin="*" />
<link data-rel="preload" href="archive/game.public.der0" as="fetch" crossorigin="*" />
Conclusion
Preloading all the assets resulted in the fastest time to game start. However, it delayed the Largest Contentful Paint metric. End users may actually perceive this as being slower, since they'll be staring at a blank page for about a second longer before the loading screen appears.
The best balance I found was to prioritize dmloader.js, then preload every other asset the moment dmloader.js finishes downloading. This didn't slow down the Largest Contentful Paint, and it sped up the total load time.
@thinknathan that's great research! I would probably not have thought of using <link rel="preload" to solve this issue. We will definitely experiment with this!
@thinknathan that's great research! I would probably not have thought of using
<link rel="preload"to solve this issue. We will definitely experiment with this!
Using preload for this purpose is not a good idea, as it will dramatically increase the time it takes for the preloader + logo to appear.
From my view, this request can be solved by a small modification of dmloader.js.
And we can even go further and embed .json with the list of archives directly into the html template, so that dmloader.js will start downloading all files simultaneously from the very start of the download.