Add loading bar to web template#740
Conversation
| import init from "./build/bevy_app.js"; | ||
| init().catch((error) => { | ||
| const wasmPath = "./build/bevy_app_bg.wasm"; | ||
| const wasmSize = null; |
There was a problem hiding this comment.
Reading this by itself is quite confusing. I wonder if we need a more visual indicator for the template replacement, especially so that users can use it for their custom index files.
But that issue existed before, so it probably makes sense to tackle it in a different PR
There was a problem hiding this comment.
The three calls to replace are also rather ugly in the Rust code.
| <noscript>JavaScript support is required to run this app</noscript> | ||
| <div id="loading-screen" class="center"> | ||
| <span class="spinner"></span> | ||
| <div hidden="hidden" class="bar-container"> |
There was a problem hiding this comment.
I'm a fan of semantic HTML, which is also more accessible.
Can we use the <progress> element instead?
There was a problem hiding this comment.
In most cases I would absolutely agree. However, styling the progress element is a little nasty between browsers. It would require a bit more CSS than this PR adds already.
Maybe we could compromise with a few additional aria attributes?
assets/web/index.html
Outdated
| bar.style.transform = `scaleX(${stats.progress})`; | ||
|
|
||
| const text = document.querySelector(".progress-text"); | ||
| text.innerText = `${humanReadable(stats.loaded)} / ${humanReadable(stats.total)}`; |
There was a problem hiding this comment.
Nit: I think the progress indicator is a bit busy right now. Not yet sure what I would prefer, maybe just the loaded size or a percentage? Even though the percentage is kinda redundant because of the progress bar.
|
I talked with @CorvusPrudens about this in discord offtopic and the conclusion we came to is that the data here seems to not indicate a useful raw MB size display. There was talk of it being used to inform users on metered or slow network connections, but the mb size here is pre-determined and is notably not the wire size, so can not be used to reliably inform a user's network-connection related decisions. So while the mb data can produce a correct and useful percentage, it can not be actioned by a user who would read the raw mb counts (and it is unclear exactly which mb the count refers to in the current display). As a result: I would suggest using only the percentage for the loading text and removing the raw mb counts. Including the percentage, however, could increase the legibility of the download progress by allowing users to read the percentage rather than estimate the progress fill percentage. |





Bevy's Wasm binaries frequently come in at 20+ MBs, even after compression. Depending on the speed of the server or a user's internet connection, downloads can take quite a while. Without any concrete indication of progress, some users get frustrated and leave.
With small changes, we can introduce a progress bar for the Wasm download phase.
Technical considerations
Since we can't rely on the
Content-Lengthheader for the size of the Wasm,1 we need to embed the size into the HTML ahead of time. We also need the URL for both the generated JS and Wasm, since we need to fetch the Wasm binary directly. Consequently, this PR introduces two new template parameters. This potentially introduces more points of failure and some additional maintenance burden.This also brings the role of the default
index.htmlinto question. Should is serve as a barebones starting point for Bevy users, or should it provide the best UX we can manage within reason?Having participated in Bevy Jam 7, I believe the latter is a better direction to strive for. To my knowledge, every team that used the CLI made no changes to the default template. Among other issues, the slow downloads contributed to a somewhat poor experience playing these games in the browser. With a few changes, including this PR, I think we'll give both devs and players a much better impression of Bevy as a whole.
Details
I'm not attached to the exact visual presentation of this PR. Maybe the spinner should be removed when we have the length information. Maybe the bytes should actually just be a percentage. The main purpose here is to propose that we take this direction in one form or another.
Also, I acknowledge the effort on the CLI will largely be focused on upstreaming via the new goals, so this may sit around for a while. I plan to make some other UX improvements in the meantime.
Footnotes
A resource's
Content-Lengthheader doesn't reflect its full size when compressed, and may even be omitted entirely. Since the fetch API only provides uncompressed chunks when using aReadableStream, theContent-Lengthwon't match the chunks when transfer encoding is applied. Thus, you need to know the size of the uncompressed resource if you want accurate progress. ↩