Search code examples
htmltwitter-bootstrapgoogle-chromebrowsersafari

Bootstrap 3 gallery page crashes only on mobile


I have a static HTML page with around 55 png images on it (~7MB total), displayed in the bootstrap 3 grid. When I visit the page on iPhone (both Chrome and Safari), the page refreshes automatically after 1-2 secs., and then it crashes. On the desktop, everything works fine:

https://teilecdn.com/test.html

Images are very big (3000x4000 pixels). When I replace the src of the images with a placeholder (https://via.placeholder.com/300), the page loads correctly, also on mobile. I discovered that images are the issue here, but I have no idea how to debug this problem. I tired with devtools, but on desktop everything works fine (even if I switch look from desktop to mobile in devtools).

Is this happening because of some special behavior of mobile browsers? Some image total size limitations?

EDIT: I just discovered that if I remove bootstrap.css, then page is not crashing.


Solution

  • I checked my iPhone crash logs via Xcode and get the following:

    error   13:58:49.424690+0000    MobileSafari    0x10b0500c0 - GPUProcessProxy::didClose:
    error   13:58:49.424722+0000    MobileSafari    0x10b0500c0 - GPUProcessProxy::gpuProcessExited: reason=Crash
    error   13:58:49.424772+0000    MobileSafari    0x10c005880 - [PID=634] WebProcessProxy::gpuProcessExited: reason=Crash
    error   13:58:49.441675+0000    MobileSafari    Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}>
    error   13:58:49.441700+0000    MobileSafari    0x10b01c120 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'GPUProcess Background Assertion' for process with PID=633, error: Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}
    

    Would appear that the webpage is causing the GPU to crash. On further investigation it appears iPhone has a memory limit when using UIWebkit which is in the region of 10MB.

    The workaround appears to be moving from IMG to background-image on the parent as per this demo: https://dev.cratrr.com/74841828/

    <div class="col-sm-3 col-xs-4">
        <div class="panel panel-default panel-unit kawasaki-border-hover">
            <div class="panel-body">
                <img src="https://teilecdn.com/kawa/diagrams/0d9e42128505943c1bd5c8832878b499.png" onerror="this.onerror=null;this.src='https://i.imgur.com/lQfiJGA.gif';" alt="Unit" class="img-responsive img-unit">
            </div>
            <div class="panel-footer">ANTRIEB</div>
        </div>
    </div>
    

    becomes

    <div class="col-sm-3 col-xs-4">
        <div class="panel panel-default panel-unit kawasaki-border-hover">
            <div class="panel-body" style="background-image:url(https://teilecdn.com/kawa/diagrams/0d9e42128505943c1bd5c8832878b499.png);"></div>
            <div class="panel-footer">ANTRIEB</div>
        </div>
    </div>
    

    With some additional CSS targeting .panel-body:

    .panel-body {
        background-size:contain;
        background-position:center;
        min-height:300px;
        height:auto;
        background-repeat:no-repeat;
        max-width:100%;
    }
    

    The only thing this misses would be your onload error handling.

    I would also consider using some lazy loading for slower networks!