28

In order to keep the IM Client logged in at all times Facebook avoids full page loads by using AJAX to load its pages before inserting them into the document.

However, during Facebook AJAX requests the browser appears to be visibly loading; the reload button changes to an X, and the progress indicator built into the browser indicates loading/waiting etc)

I've been able to implement AJAX based navigation successfully, but my browser doesn't show any indication of loading (since the requests are asynchronous) how do Facebook do it?

reach4thelasers
  • 26,181
  • 22
  • 92
  • 123
  • "to keep the IM Client logged in at all times" The IM stays at the same state, even if opening links in a new tab… – feeela Jan 18 '12 at 19:09

3 Answers3

24

The browser displays the loading state when there is an element in the document which is loading. Ajax requests are made entirely from within JavaScript; the document is not affected and so the loading state isn't triggered.

On the other hand, most of Facebook's requests are made by inserting a <script> tag into the document, pointing to a JavaScript file containing the data they want. (Essentially JSONP, except they use a different format.) The browser will displaying its loading state because the <script> tag is an unloaded element in the document.

This technique/JSONP can expose your site to security risks if you're not careful, because cross-site requests are allowed. Facebook deals with this by generating random URLs for each resource, which are sent to the browser in the initial page load.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • 1
    Thanks for the insightful answer. However when I try this approach (create a `script` tag, set its `src` to my JSON controller, append it to my `head` or `body` tag, the browser doesn't display loading indicator. The result come back successfully and I see the added script tag in my page source. Also I have added `Sleep` method to my server side method to simulate a long-running process, to see the loading appears. But still no luck. Any ideas? – Kamyar Mar 27 '12 at 02:20
  • 2
    P.s. When I use `IFrame`, everything works fine. but couln't do it with `script` tag. – Kamyar Mar 27 '12 at 02:21
  • @Kamyar I'm actually not sure. I came back and tried to do this again myself a little while ago, and I had the same issues that you are describing. I am quite sure that it was working when I wrote this answer... I'm not sure if something has changed or if I got something wrong here. – Jeremy Mar 27 '12 at 02:30
  • This is driving me nuts! no knowing how they do it. I'd appreciate it if you share it here when you find anything. I'm currently out of ideas. – Kamyar Mar 27 '12 at 02:43
  • They use iframes for things that should "feel" like a page load (if you inspect the page while triggering a "page" load you can briefly see an "iframe_transport" iframe appear at the bottom of the document and then get removed). It's notable that this approach does not work on all browsers. Try it in Safari, and you won't see any indication that the page is loading when you navigate from your feed to your wall like you do on a browser like Chrome. – Dtipson Nov 29 '14 at 02:28
11

Facebook uses a tool they developed called Big Pipe to basically stream their site to the client in chunks. They send an initial script tag with a bare DOM to the client, and the script loads modules on the page asynchronously - the idea being the client is presenting module 1 while the server is fetching module 2, therefore improving load time.

On top of that, they use a technique called long polling. With HTTP 1.1 they can take advantage of a persistent connection and not have to worry about timeouts. When the page is rendered, the client-side script makes an AJAX request to Facebook to essentially "listen" for an event. It will sit there and listen until an event happens. In the meantime, the browser will appear to be "loading" data.

When an event is triggered on Facebook's end (say someone commented on your wall post), FB will send that response back to the client to fire the respective callbacks (like popping up a little tool-tip letting you know about the comment) and IMMEDIATELY send another request to FB to listen for the next event.

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
4

Facebook use iframes for communication when they want the browser 'busy' status to appear. You can use iframes to do cross domain ajax by having the iframe call functions in the parent window.

skarE
  • 5,880
  • 2
  • 23
  • 23
  • 1
    Note that whether iframe loads trigger the browser's busy indicator is entirely browser dependent. Safari and later IEs have chosen to suppress these indicators for iframes (which imho is silly/bar for users, but it certainly makes their browsers "appear" faster by having fewer things that trigger busy states) so even that technique will not work. – Dtipson Feb 19 '15 at 22:17