abstreet
abstreet copied to clipboard
Web client performance
Some different ideas for smoothing out the web client:
- The
.wasm
binary is around 50MB, which makes initial startup time quite sad. Gzipped is around 20MB. I can't find any option to enable this inwasm-pack
, because I think people generally just configure their web servers to do compression on-the-fly if the HTTP client sendsAccept-Encoding
headers. S3 doesn't support this, but I think it's possible to upload a.wasm.gz
, point to it from the.html
, and set theContent-Encoding
header properly. Just need to test this and make sure browsers understand it. - Keep the
Scenario
for the current map in memory after loading it from a file. Otherwise, everytime the player resets to midnight in many gameplay modes, they have to download the file again! - In
wasm_loader::FileLoader
, display a progress bar with bytes downloaded / total length. I foundset_onprogresss
forXmlHttpRequest
, but actually, we're currently usingweb_sys::Request
, which is different. Can we switch?
I can't get gzipping the .wasm to work. I set the headers correctly, and the browser loads the smaller file, but then breaks somewhere:
Good starter bug / help needed: on web, loading files uses fetch_with_request
, which I don't think exposes any way of tracking how many bytes have been downloaded. If we could change to something else, the loading screens on web could have a progress bar too.
https://github.com/dabreegster/abstreet/blob/14f692fc39e31c8009cf6cd91347544d3b15a841/map_gui/src/load.rs#L124
Did some quick digging on WASM binary size. I'm... a little embarrassed. In release mode, fifteen_min
is 49MB, game
is 54MB, widgetry_demo
is 47MB. That last one surprised me -- there should be way less dependencies there. But of course we use include_dir
to bundle in different parts of data/system/
. When I commented that out, game
dropped down to 16MB and widgetry_demo
to 8.7MB.
Digging into the files that're included in the .wasm by default:
- 33MB in
data/system/assets/
, because of some huge character SVG files and the music added for santa - 5.4MB for the montlake map and Seattle overview map, where the sim always starts
That first problem should be pretty easy to fix. For the second, maybe it's time to make the .wasm start with Map::blank
and immediately jump into a loading screen for a real map. Ideally we can even stick a ?map=leeds/north
query parameter on the URL and use that.
Woops, tagged the wrong issue on b4e72debcfdf5f51503f68aca8d31ec84c91795d.
game is now 18MB. gzipping brings it down to 8.5MB, so figuring out how to make S3 + browsers do that is still worth it.
Just to say, I find the web performance pretty good. Great work on this issue!
Happened across https://github.com/carllerche/tokio-serde and https://docs.rs/destream/0.1.2/destream/ for possible async serde decoding
Web client error on open, gives this error when loading maps - and 'OK' won't dismiss:
(game application is working fine)
Whoops, fixed now. I forgot to upload the new web client after a flurry of map format changes yesterday. Thanks for the heads up!
the loading screens on web could have a progress bar too
https://github.com/MattiasBuelens/wasm-streams/blob/master/examples/fetch_as_stream.rs
This library looks like it should work. Going to first merge FileLoader
and RawFileLoader
, then try to use this.
https://old.reddit.com/r/rust/comments/t0fuyf/announcing_rust_1590/hya5dgx/
[package.metadata.wasm-pack.profile.release] wasm-opt = ['-Os']
Good starter bug / help needed: on web, loading files uses
fetch_with_request
, which I don't think exposes any way of tracking how many bytes have been downloaded. If we could change to something else, the loading screens on web could have a progress bar too.https://github.com/dabreegster/abstreet/blob/14f692fc39e31c8009cf6cd91347544d3b15a841/map_gui/src/load.rs#L124
Here is a way to do it in JavaScript that I found : https://javascript.info/fetch-progress#:~:text=To%20track%20download%20progress%2C%20we,in%20the%20Streams%20API%20specification.
I guess this can similarly be implemented in Rust using web-sys
.