Horrible Safari Performance

Getting terrible performance with safari on many of the THREEjs examples.

Possibly related to Horrible 3D/Three.js performance in latest Safari on macOS

Running the Keyframes example: three.js examples

  • Safari 15.5 is giving me 3-7 fps
  • Chrome 101.0 is giving me 60fps

Configuration:

  • 2019 MacBook Pro with Radeon Pro Vega 20 @ 4 GB
  • internal 15" retina display at retina resolution (2:1)
  • external 27" LG 5K retina display set to retina resoultion (2:1)

Regression testing:

  • Safari speed appears to be related to with # of pixels being animated.
  • I can get about 60fps with a tiny window
  • but fullscreen it drops to about 1-4 fps
  • I’m using gfxCardStatus which indicates the Dedicated GPU (Radeon Vega) is in use.

Ok, I think I see the problem. Here’s a comparison of Safari 15.5 vs. Safari Technology Preview 15.4.

15.5 is clearly using the iGPU, even though I’ve got 2 monitors and the rest of the system is using the dGPU:

15.4 is clearly using the dGPU, as it should be:

Oddly, this bug was reported in the Safari 13 to 14 update, seems to have been fixed as per https://twitter.com/Supermoos/status/1423196071711363076 , but then re-surfaced again in Safari 15?

As a workaround I added

	if (detectedOS == "mac" ) {
		contextPowerPreference = "high-performance";
	}

and things are working normally again.

This is frustrating though, as I have packaged software in the field which is now breaking when people do their macOS / Safari upgrades.

2 Likes

Just want to mentioned that I did consider to suggest high-performance as a default but it is actually not recommended by the WebGL spec.

high-performance: Indicates a request for a GPU configuration that prioritizes rendering performance over power consumption. Developers are encouraged to only specify this value if they believe it is absolutely necessary, since it may significantly decrease battery life on mobile devices. Implementations may decide to initially respect this request and, after some time, lose the context and restore a new context ignoring the request. Applications that request high-performance should test and maintain robust context loss handling, as User Agents are very likely to decide to lose background high-performance contexts.

So three.js uses default which means some devices/browsers might decide to not use the dedicated GPU.

1 Like

I think that’s appropriate, in that I think the current macOS/Safari/WebKit behavior is clearly a bug: the system should not use the iGPU for WebGL when the dGPU is being used for the monitors, as it clearly leads to bad performance; and I would expect it to use more power overall.

I wonder if you should put a browser detection banner on ThreeJS examples “Hey, we see you are using Safari verion X thru Y which has a bug… you may see worse performance” ?