WebGL Performance on Safari and Apple Vision Pro
Safari–especially on iOS–has always been considered the pinnacle of performance challenge for developers building on the 3D web. The Metal-based implementation of WebGL, together with the unique performance characteristics of WebKit make it particularly interesting to deal with.
In this article, we give you some insights into how you could improve the performance of your WebGL apps on Safari.
Apple Vision Pro
In recent days with the launch of the Apple Vision Pro, WebGL performance on Safari has gained even more importance as Apple Vision’s version of Safari has inherited all the performance characteristics of Safari on MacOS and iOS.
We will be posting a full article on WebXR with Apple Vision Pro soon, subscribe to our newsletter to get notified.
Wonderland Engine on Apple Vision Pro
If you are already using Wonderland Engine, we have good news: all the optimizations we did for our 0.9.0 release translate over to Apple Vision Pro.
Developers with access to the Apple Vision Pro are reporting great performance on their Wonderland Engine based apps:
Optimizing for Safari
If you are on another framework, make sure to have a look at our WebGL Performance Profiling blog post. That blog post contains tips on how to find the bottlenecks of your application to find out what to optimize.
Additionally, below are some notes on what you might find in Safari while profiling. These are not one-size fits all, profile your application to find out which of these are cause you trouble.
Bottlenecks
Here are a few more characteristic issues you might encounter when working with WebGL on Safari:
Uniform Buffers
Because of how Apple’s graphics API Metal differs from WebGL, Safari needs to emulate a WebGL-style uniform buffer under the hood. This emulation incurs some difficulty in predicting the performance of UBOs: some uses will be fine, while others could incur a 150ms hitch when trying to upload data at the wrong moment in time.
This snippet of code
from the Metal implementation of Angle (which is used by WebKit to implement
the WebGL2 API) points to the implementation of the GLES equivalent to
WebGL’s bufferSubData
.
It helps us appreciate to which lengths browser developers go to provide us
with a consistent graphics API.
It also shows to which lengths the Wonderland Engine team goes for you to
understand browser performance and optimize for you.
There was a lot of dismay around Safari taking a long time to release support for WebGL2. Contrary to speculations that they might never support it, they did release WebGL2 support in September 2021 with Safari 15. Reading the WebKit and Angle code raises some empathy around why it might not have been an easy task to get done.
WebGL State Access
WebGL’s getParameter
function has some performance surprises in store
for you. What seems like a harmless function can cost a lot of performance
budget.
WebGL Error
While checking errors with getError
is generally a good idea, avoid it
outside of your frame callback, since it can be more expensive than it
should be.
Memory and Limits
WebGL Safari will report limits for texture sizes, layers, uniform buffer sizes and more. A good tool to check these limits is webglreport.com.
While Safari will allow you to allocate up to these limits in theory, you might find that this can cause your page to crash.
To use memory resources on iOS more efficiently, Wonderland Engine provides a feature we call Texture Streaming, to dynamically swap pieces of textures in and out of memory based on what is currently needed in the frame. It is enabled by default.
Closing Words
We will be following up with a detailed blog post about WebXR on Apple Vision Pro in short. Subscribe to our newsletter to get notified when we release it.
Until then, we hope you give Wonderland Engine a try! Especially when coming from Unity, Wonderland Engine is easy to learn.
Make sure to join our Discord server as we are happy to point you to the right resources to get started.