StrandedKitty / streets-gl

🗺 OpenStreetMap 3D renderer powered by WebGL2
http://streets.gl
MIT License
661 stars 49 forks source link

Long loading time: Add option to cache textures locally? #37

Open Kovoschiz opened 1 year ago

Kovoschiz commented 1 year ago

Every time a new tab is opened, all the texture files has to be transferred again. This is very slow and inconvenient to verify editing. Can they stay persistent in local storage? (Don't know how browser works) At least for the session.

StrandedKitty commented 1 year ago

I think that caching already works (i.e. nginx provides Cache-Control: no-cache header). For me it seems to work, the browser caches all the files and only sends requests to verify that the cached versions are the most recent, which still takes some time. But I think the browser cache gets reset pretty often, probably because there's too much data to store.

What I wanted to try first is to compress all the textures, this should help to some extent.

russss commented 1 year ago

Removing no-cache from your cache-control header will stop the browser hitting the server at all if it already has the image cached, which will speed things up a lot, as long as you change the file name if the contents change.

Also, I don't believe you have HTTP/2 enabled on nginx. Enabling that should speed up the texture loading a lot, as it allows for more request parallelism.

StrandedKitty commented 1 year ago

@russss I've initially added no-cache to make the client update files when CD rolls out new changes. Maybe there's a way to somehow reset the cache after rebuilding the app, I don't know. It's my first time building a CD.

I will look into HTTP/2, thank you.

StrandedKitty commented 1 year ago

I've enabled HTTP/2, but the texture loading is built in a way that requests are executed one by one, so there's nothing to gain from parallelism right now. I should probably make textures and other resources load in batches, several items in each batch.

russss commented 1 year ago

I reckon you can probably fire off all the requests at once and the browser will deal with the parallelism - that's what it would do if there are a load of images on a page.

Kovoschiz commented 1 year ago

So I'm reading the cache entry, and learning caching. A study question: Can you use must-revalidate instead of no-cache ?

StrandedKitty commented 1 year ago

So I'm reading the cache entry, and learning caching. A study question: Can you use must-revalidate instead of no-cache ?

It seems like the only difference is that must-revalidate takes max-age into account. So if the local resource is younger than max-age then no revalidation is done. And with no-cache revalidation is always done.

But I don't think must-revalidate with max-age would work for this app because it's not really possible to specify meaningful max-age value. Files can be updated at any time by the CD pipeline.

StrandedKitty commented 1 year ago

I've added automatic texture compression to reduce bundle size, so now the bundle is roughly 3 times smaller (~34MB instead of ~100MB).

eliasp commented 1 year ago

You might want to set the mtime of files based on the last commit that changed them. Right now it seems, all files have the same mtime (set at the time of the build).

This mtime can then be used by your webserver to respond to ETag/max-age requests to (in-)validate cached files and deliver updated ones.