Performance and Usability Advice for Commercial Site

The files average 3-5 MB (2MB jpeg + 1MB geometry + 2MB morph target information).
Using a GLTF loader with the 5MB file saved as a .glb, orbit controls, and standard webgl renderer, is it possible for 95%-100% of people across most modern devices and browsers (modern as in, within the past 4 years) to be able to use his site? Is what I recommended viable? To reduce bounce rate, the 3D model has to load within 3 seconds. What is an acceptable size or is 5MB acceptable for 3 seconds?

1 Like

Just a side question while we’re on the topic. How much does lighting affect performance? I don’t think it’ll affect loading time by more than a sec?

Lots and lots of variables. Usually you’d pay someone who knows all this for consultation :slight_smile:

But one thing is for sure, lighting should really have no impact on load times.


I would say no. A lot of mobile devices will have trouble to download the 5 MB within 3 seconds. A good starting point might be to further reduce the file size of the textures. You are already using JPEG but there might be some room to reduce the resolution or use an aggressive compression rate.

A lot of smartphones support PVRTC or ASTC texture compression. You might want to load specific assets/textures for these devices if they support the respective format. It depends on the texture but in general it’s possible to halve the file size with ASTC compared to JPEG without seeing noticeable differences.

1 Like

Interesting… what do you think is a good file size for 3 seconds then? Also, I’d like to know how long you think it would take to load 5MB?
EDIT: The US, ranked 44th, has an average mobile download speed of 26.32 Mbps in 2017 according to
If my calculations are right, isn’t that a 2.5MB/s download speed? Or are there other factors at play here?

What is the actual model? It could be interesting for the compression or (maybe progressive) loading approach

1 Like

I’m told they’re custom design water bottles. By “progressive loading” are you referring to “streaming”? My understanding is that it works a little like SketchFab where the model is loaded part by part?

There are various things you can do progressively and depends on the case what will fit best. One thing you definitely can do is using low res textures first since that seems to require a lot memory - or using for example a single color only showing the model first can be another approach, in most cases it’s just important to show something as fast as possible, not letting people stare at the void.

Maybe a low-poly proxy might suit your needs, but the 1 MB geometry is fine to load entirely. I would definetly separate the morph data though if it isn’t required in initial state. As long as you are loading any data i would recommend to show a loading indicator, since especially for low-res stages it can give a wrong impression to non-technical users which might see it as final stage and might quit at this point.

1 Like

Great advice! How would I separate the morph data? I think that is the most problematic area.

I use a custom modular binary format, i can’t tell about gltf since morph data mostly is attached/related to the modelling tool. You could also just extract them though. When the model is loaded just download the buffers as blob so you have a single separate file and export that gltf without morph targets again. Next time you load the blob and add the targets again. But that’s just a quick solution.

You can probably just export a gltf with only geometry, and one with only the targets so they are separated. @donmccurdy can answer that i suppose :smile:

1 Like

Is your user in Sweden, USA (near a big city or somewhere i the country side) or Africa? I think there are probably some charts or historical data. For example if you’re serving to users who live in city X in country Y using Z service provider, your average transfer rate is some_amount_of_KB / second if you divide your file size (5mb) by this rate you will get the number of seconds it takes to download the asset.

1 Like

Average is not really useful here, you need to pick a lower range that you want to support - like 95% of users.

I recommend testing with
You can throttle loading time to see what it will be like to load your site on an old phone using 3G.

Note that you’ll never be able to get ‘under 3 seconds for all users’. You have to say something like ‘under 3 seconds for all users with a Galaxy S5 or better on 4g’. Even then, it’s very tricky to test this.

1 Like

Yeah, each morph target is really just another copy of the mesh vertex positions (and possibly normals and tangents). So if you export N separate meshes, you can always join them together into a single mesh with morph targets in three.js. Something like:

mesh1.geometry.morphAttributes.position = [

It’s also technically possible to split the binary data of a glTF file across multiple files, like:

- model.gltf
  - geometry.bin
  - morph.bin

But this would require custom processing of the file – a modeling tool exporter won’t do that for you. Easier to just use separate meshes in this case.


All of this stuff mentioned here is the experience you pay $$$ for, once someone lays out this architecture, you can pay $ for it to actually be developed. ($$/hour)