5

Facebook's Javascript SDK has a method called getLoginStatus that stalls (and never fires the callback passed into it) while an image request on the page also stalls (i.e. the browser doesn't receive a 200 or 404 for a very long time.)

If you wait an extremely long time and the browser (?) finally closes out the attempt to fetch the image, the SDK continues on its merry way.

What might be going on, and is there a way to prevent it? It's awfully inconvenient when a user can't sign in or sign up just because of an image request.

Gurfuffle
  • 784
  • 12
  • 32
  • Does this happen with only one stalled image? – Emil Vikström Jul 17 '14 at 15:03
  • Yup. That's actually the case in which this showed up. One image request was labeled as "pending" for a minute plus -- and was completely blocking `getLoginStatus` method. – John O'Neill Jul 17 '14 at 15:10
  • 3
    Just to make sure, you embedded the JS SDK asynchronously? And it is actually the request that the method tries to make itself that gets blocked, and not the _call_ of the method? – CBroe Jul 21 '14 at 16:30
  • 1
    Have you seen this [question](http://stackoverflow.com/questions/5741256/fb-getloginstatus-never-fires-the-callback-function-in-facebooks-javascript-sdk)? – Raidri Jul 22 '14 at 16:20
  • Do you have a test page to reproduce this issue? – Roemer Jul 23 '14 at 13:05
  • @CBroe Yup, the JS SDK is loaded asynchronously, and it does seem like it's the actual *request* getting blocked, not the call of the method. @Raidri Yeah, I was checking that out a bit. Unfortunately disabling caching / setting the second param to `true` doesn't help (nor do any of the other suggestions.) @Flaxfield Not yet, but I'll try to set something up soon! – John O'Neill Jul 23 '14 at 15:59

3 Answers3

2

Blocking (HTML):

<img src="..." />

Non-Blocking (with CSS):

#someDiv {
    background-image: url(...) no-repeat;
    width: xxx;
    height: xxx;
}

Non-Blocking (with JS):

var img = new Image();
img.onload = function () {
    document.getElementById('someDiv').appendChild(img);
};
img.src = "...";

Try with solution number 2 or 3 - there are also many preloader plugins for JavaScripts making it easier for you to load a lot of images asynchronously, for example: http://thinkpixellab.com/pxloader/

Another solution would be to load smaller images first and load the hires ones asynchronously.

andyrandy
  • 72,880
  • 8
  • 113
  • 130
  • Loading images asynchronously is not an option. It destroys a lot of browser optimizations among other things. The Facebook SDK is the foreign element here, not the images. – Emil Vikström Jul 28 '14 at 22:27
  • as far as i can see, the problem is that the image takes too long to load and it´s blocking, so that´s pretty much the only option if you want to load the sdk faster. but there is another solution - not a good one though. – andyrandy Jul 29 '14 at 08:05
  • may i ask why someone would downvote my answer? the blocking image IS the problem, as it´s clearly stated in the question. – andyrandy Jul 29 '14 at 09:10
1

When you use the initialization code from the Facebook SDK website, by default it wants to wait for the page to be fully loaded be for running certain events, like the fbAsyncInit function.

I'm not sure of an "officially supported" way to bypass this, but you could load the Javascript source yourself and call the routines outright (i.e. not in the async wrapper).

This is a barebones example that stalled like you mentioned using the Facebook SDK initialization procedure but works fine with this workaround.

<html>
<head>
    <title>This is a test</title>
    <script src="http://connect.facebook.net/fr_FR/sdk.js"></script>
    <script language="javascript">
    <!--
    var loggedIn = false;
    var authenticated = false;

    FB.init({
        appId      : '{your app ID here}',
        xfbml      : true,
        version    : 'v2.0'
    });

    FB.getLoginStatus(function(response) {
        if (response.status === 'connected') {
            // the user is logged in and has authenticated your
            // app, and response.authResponse supplies
            // the user's ID, a valid access token, a signed
            // request, and the time the access token 
            // and signed request each expire
            var uid = response.authResponse.userID;
            var accessToken = response.authResponse.accessToken;
            loggedIn = true;
            authenticated = true;
        } else if (response.status === 'not_authorized') {
            // the user is logged in to Facebook, 
            // but has not authenticated your app
            loggedIn = true;
        } else {
            // the user isn't logged in to Facebook.
        }
    });

    function testLogin()
    {
        alert("Logged in: " + loggedIn + "\nAuthenticated: " + authenticated);
    }
    // -->
    </script>
</head>
<body>
Testing!
<button onclick="testLogin()">Test login?</button>
<img src="http://deelay.me/5000/ http://example.com/image.gif">
</body>
</html>

I'm not sure how this will affect integration with your site, but I can't imagine it would be a problem. If anything I suppose it's worth a shot!

Anthony
  • 2,256
  • 2
  • 20
  • 36
0

Do you have any adblockers setup? I had a similar problem with a different API and Adblock Pro was causing some issues.

Steve Tauber
  • 9,551
  • 5
  • 42
  • 46