Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageBitmapLoader: Safari has increased memory usage migrating from Three r165 to r166. #30416

Open
stevexbritton opened this issue Jan 28, 2025 · 5 comments

Comments

@stevexbritton
Copy link

stevexbritton commented Jan 28, 2025

Description

When upgrading from Three r165 to r166 my GLB models consume approx 50MB more memory on Safari MacOS 15.1.1 and iOS 18.2. This seems like a large increase and I just wanted to check that this is to be expected. I have deliberately not used an environment map because I know they grew in size with release r161.

Reproduction steps

On MacOS

  1. Run Activity Monitor and filter for https://vykingsneakerkitnative
  2. Run a new Safari window and load page: https://vykingsneakerkitnative.s3.eu-central-1.amazonaws.com/SteveTest/tmp/memory-r165.html
  3. Run a new Safari window and load page: https://vykingsneakerkitnative.s3.eu-central-1.amazonaws.com/SteveTest/tmp/memory-r166.html
  4. Compare their memory usage in Activity Monitor.

Code

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Three r165</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

    <script type="importmap">
    {
      "imports": {
        "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
        "GLTFLoader": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/GLTFLoader.js"
      }
    }
    </script>

    <script type="module">
        import * as THREE from 'three'
        import { GLTFLoader } from 'GLTFLoader'

        document.addEventListener('DOMContentLoaded', () => {
            console.log(`Three version ${THREE.REVISION}`)

            const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
            camera.position.z = 1;
            const scene = new THREE.Scene();
            scene.background = new THREE.Color(0xaaaaaa);

            const renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setAnimationLoop(animation);
            document.body.appendChild(renderer.domElement);

            function animation(time) {
                renderer.render(scene, camera);
            }

            const loader = new GLTFLoader();
            loader.load('https://sneaker-window.vyking.io/vyking-assets/customer/vyking-io/yeezy_boost_700_carbon_blue/model_l.glb', function (gltf) {
                scene.add(gltf.scene);
                console.log(gltf.scene)
            });
        })
    </script>
</head>

<body>
</body>

</html>

Live example

https://vykingsneakerkitnative.s3.eu-central-1.amazonaws.com/SteveTest/tmp/memory-r165.html
https://vykingsneakerkitnative.s3.eu-central-1.amazonaws.com/SteveTest/tmp/memory-r166.html

Screenshots

Image

Version

r165 & r166

Device

Desktop, Mobile

Browser

Safari

OS

MacOS, iOS

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 28, 2025

Do you see an increase in memory when using a scene with a simple box geometry? So without GLTFLoader?

Maybe it's because starting from r166, GLTFLoader uses ImageBitmapLoader by default for loading textures which could affect the memory allocation.

@stevexbritton
Copy link
Author

I think you are correct, because when I use the r165 GLTFLoader with the r166 three.module.js the size matches the pure r165 example. The question now is why. Do you have any thoughts? 50M is a high price to pay, especially as I'm targeting iPhones, and I think the size difference increases with my larger models.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 30, 2025

I don't know why this happens. Maybe it's worth to report this issue at the Webkit bug tracker: https://bugs.webkit.org/

@donmccurdy
Copy link
Collaborator

donmccurdy commented Jan 30, 2025

(Context for future readers: ImageBitmapLoader decompresses a texture asynchronously before upload to GPU, avoiding dropped frames during upload. Otherwise the texture is decompressed during the upload, potentially blocking the main thread and dropping frames. In either case the texture is fully decompressed on the GPU)

I wonder if the difference might be that the texture object retains a reference to the uncompressed data on the main thread? Whereas that uncompressed data might only be kept on the GPU, otherwise?

I'm not sure what the expected behavior is, or whether it would be different in Chrome. But perhaps one way to test this would be to delete the in-memory reference to the texture data after the first frame renders after loading the texture (delete texture.source) and see if memory decreases as expected. This might of course cause other problems, but it would be helpful to know.

@GitHubDragonFly
Copy link
Contributor

GitHubDragonFly commented Feb 4, 2025

@stevexbritton if this might be an option for you then maybe also try optimizing and compressing your models.

Just by using the model's URL from your code, I could load it in my viewer and then re-export it to GLB format with DRACO compression and WEBP textures set at max 2048 x 2048. After loading this new GLB file it showed half the memory usage in Firefox browser on Windows.

You can do this yourself by loading your model into the gltf.report and then running the script and applying the compression (just change WEBP resolution to whatever works for you).

Also, observe the details of re-exported model to make sure that they are good enough for your usage.

EDIT: If you want then I could attach 3 different versions of your model, each with either of AVIF, KTX2 or WEBP textures. You could compare the sizes and load each one of these into the gltf.report to see their quality and memory usage.

@Mugen87 Mugen87 changed the title Safari has increased memory usage migrating from Three r165 to r166 ImageBitmapLoader: Safari has increased memory usage migrating from Three r165 to r166. Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants