google / model-viewer

Easily display interactive 3D models on the web and in AR!
https://modelviewer.dev
Apache License 2.0
6.71k stars 799 forks source link

iOS 17 Safari Privacy Protections slows down rendering with multiple model viewers on page #4587

Closed pushmatrix closed 4 months ago

pushmatrix commented 7 months ago

Description

Well this is fun. Safari in iOS17 and Sonoma introduced "Advanced Tracking and Fingerprinting Protection". This is on by default in private tabs. It seems to throttle the renderer (or at least canvas operations) in order to prevent device fingerprinting.

This article is light on details, but includes the line

Lastly, Advanced Privacy Protection will add ‘noise’ into several key fingerprinting vectors, such as 2D Canvas, Web GL, Web Audio and Screen a& Window geometry.

Live Demo

Desktop

  1. In Safari (on OSX Sonoma) open a private tab and go to https://adhesive-hypnotic-pantry.glitch.me
  2. Rotate the astronaut around (it will be sluggish)
  3. Go to View -> Reload reducing private protections
  4. The page will reload, now rotate the astronaut and it will be normal performance

Mobile

  1. In Safari (in iOS 17) open a private tab and go to https://adhesive-hypnotic-pantry.glitch.me
  2. Rotate the astronaut around (it will be sluggish)
  3. You can turn off privacy protections in General -> Safari -> Advanced -> Advanced Tracking and Fingerprinting Protection
  4. Reloading the page will have normal performance again

I even get this popup sometimes

Screenshot 2023-12-06 at 11 51 13 AM

The same behaviour can be seen on sites that have multiple canvas elements. Ex, this one is written in vanilla webgl (not three): https://ciechanow.ski/bicycle/, and the issue shows.

This behaviour is not present on sites that have a single canvas it seems. For example, this works fine: https://model-viewer.glitch.me. And the threejs example of using a single canvas and scissor cutting out multiple scenes also works fine: https://threejs.org/examples/?q=multiple#webgl_multiple_elements

It seems like it starts getting sluggish after three or some canvas elements. I need to investigate further, but really not sure what a fix could be here.

Version

Browser Affected

OS

pushmatrix commented 7 months ago

So it seems like if each canvas has its own webgl context, then it's fine. Example: React-three-fiber scene with multiple separate canvases: https://pydwvq.csb.app That is smooth with or without the protection on.

So I'm led to believe it's likely the canvas2D drawImage operation that is the root issue with model viewer and other apps that share a single webgl context across canvases

pushmatrix commented 7 months ago

Oh interesting, I guess bypasses doing drawImage if there's only one of the page. That must explain why it renders just fine with one model viewer

elalish commented 7 months ago

Indeed, this is one of our key performance features. Sharing the context is dramatically more efficient for both loading time and GPU RAM usage, but we save a copy when there's only one canvas (which is pretty common). I think Apple's getting a major false positive here - have you reported a WebKit issue yet? @grorg in case he can escalate this inside Apple.

pushmatrix commented 7 months ago

Just filed it here: https://bugs.webkit.org/show_bug.cgi?id=266181

I made a minimal test case too: https://glitch.com/edit/#!/evanescent-traveling-radio?path=index.html%3A84%3A0

pushmatrix commented 4 months ago

Can confirm this is fixed in iOS 17.4 following the resolution of: https://bugs.webkit.org/show_bug.cgi?id=266181

elalish commented 4 months ago

Thank you for helping to get that resolved!

grorg commented 4 months ago

FYI - I don't work on this project within Apple any more, which I why I haven't been replying to pings. Sorry. (cc @elalish)

elalish commented 3 months ago

@grog, thanks for letting us know. Any other Apple Github handle we can ping instead?