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

ThreeJs ThreeMF loader is blocking the UI while upzipping the 3MF file. #20206

Closed
2 of 12 tasks
frederik14 opened this issue Aug 28, 2020 · 8 comments
Closed
2 of 12 tasks

Comments

@frederik14
Copy link

Description of the problem

ThreeJs ThreeMF loader is blocking the UI while upzipping the 3MF file.

try {
	zip = new JSZip( data ); // eslint-disable-line no-undef
} catch ( e ) {
	if ( e instanceof ReferenceError ) {
		console.error( 'THREE.3MFLoader: jszip missing and file is compressed.' );
		return null;
	}
}

According the the JSZip documenation I assume it would be better to unzip the container asynchronously not to block the UI.

Three.js version
  • [x ] Dev
  • r120
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, ...)
@Mugen87
Copy link
Collaborator

Mugen87 commented Aug 28, 2020

Even when doing this task asynchronously, it's still done in the main thread and thus blocking the UI.

@frederik14
Copy link
Author

Depends on how JSZip is written, but I assume it releases the main thread after every chunck making the UI responsive. Explained here.

@Mugen87
Copy link
Collaborator

Mugen87 commented Aug 28, 2020

Can you please prove your assumption with a concrete live example?

Notice that the upgrade of JSZip was tried several times. It was not possible to finish it because it's necessary to retain the sync usage of 3MFLoader.parse(). More information: #19097 (comment)

@frederik14
Copy link
Author

Thanks for the reference! Tentone clearly had the same idea as me. But indeed I don't think we will be able to keep the sync behavior of the loader.parse() external API. To fix it I would suggest to extend the external API with a parseAsync() function. The original parse function of the threeMf loader will still need to use a sync unzip function. I don't know if JSZip 3 still has this behavior? I will get started creating a live example proving the performance benefit.

@Mugen87
Copy link
Collaborator

Mugen87 commented Aug 28, 2020

The original parse function of the threeMf loader will still need to use a sync unzip function. I don't know if JSZip 3 still has this behavior?

When I remember correctly, it was removed. Hence it suggested to look for a different library which provides a sync method.

@frederik14
Copy link
Author

I came to the conclusion that loading the zip file indead blocks the thread for a couple of milliseconds jsfiddle. But opening the 3mf file takes very little time compared to the total 3mf loading time. If the loader would be async it could do all the small actions in the js event queue. This would update the UI in between every small parsing action. (js event queue explained)

@donmccurdy
Copy link
Collaborator

Might be a good candidate for #19650? We could keep JSZip but move it to a worker.

@Mugen87
Copy link
Collaborator

Mugen87 commented Nov 12, 2020

After a closer performance analysis of 3MFLoader.parse(), the actual overhead does indeed not come from the unzip operation. DOMParser.parseFromString() as well as the processing of the XML document takes way more time than anything else. In webgl_loader_3mf_materials, unzipping takes 2.6 ms whereas the rest of parse() takes 1.85 seconds.

So similar to ColladaLoader, the actual overhead is produced by parsing and processing XML. Hence, marking this issue as a duplicate of #11746.

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

3 participants