javascriptiphonedebuggingsafaricrash

Debugging a iOS Safari crash "A problem repeatedly occurred"


Sometimes when visitors visit our website on their iPhone and start scrolling, Safari will show an error "A problem repeatedly occurred for ...." . When we try to reproduce the issue, nothing shows in the console log and we can't seem to find a crash report.

Is there any way to debug this issue further? When reloading the page, and doing the same action, will sometimes not result in the same error.

Tried to use developer tools via Safari on Mac. This shows nothing in the console errorwise.

Sidenote: on desktops and other mobile devices, we don't seem to have this issue.


Solution

  • This sounds like its caused by high GPU consumption.

    Test

    Open your web page in Safari, and in dev tools look for the Layers panel. This opens up a lovely interactive 3d view of the 'layers' on your page. Layers are essentially elements which require separate composition. There are many factors which can trigger this, and handily in the 3d view if you click on a layer, it'll tell you the reason for that particular layer being composited. It'll also show you the GPU used to composite that layer.

    As you interact with your page, you'll see these values update in real-time. This is really useful since you can see whether interactions and animations cause significant spikes.

    If you want a clearer idea of how a real device is impacted, you can plug an iPhone in to your laptop, and use remote dev tools in desktop Safari to get the same Layers view.

    Common causes

    See this Chromium code for a peek under the hood: https://source.chromium.org/chromium/chromium/src/+/main:third_party/WebKit/Source/platform/graphics/CompositingReasons.h;drc=a30d423812ad0d766e93b0f3a53523807b50b17b

    Something that's not completely clear from the above is that content overflowing the body on the x-axis can cause GPU spikes during scroll events.

    Note also that as a user scrolls, pinch-zooms (particularly), etc. your page, rapid redraws of these composited layers is required, because everything requires a re-render to remain sharp, since these layers are essentially bitmapped RGBA PNGs.

    Generally speaking, the larger the dimensions of the element, the more GPU is required. Which makes sense but the interesting thing about this is that you'll likely see the issue more on larger devices and/or devices with higher-density displays, e.g. Pro/Max/Ultra models of iPhone.

    How to fix

    Hopefully the above will give you an idea of what causes your issue, and you can use the evidence to start mitigating the problem. Any fixes will entirely depend on your code but in general you'll be looking to remove the number of composited elements.

    It's absolutely impossible to have no composited layers (the document root is one...) but if you have an abundance of large ones (e.g. full-page modals) then you'll have a good place to start.

    In general you might consider the following:

    I've dealt with this problem myself (GPU on one of our pages was peaking at 550mb, and is now 12mb) so if you have any questions feel free to reach out via. a comment.