they recommend loading it asynchronously, we were already
async would give us much additional benefit. However, after some non-scientific
performance tests it appeared that switching to asynchronously loading the
Facebook API could reduce the time to
DOMContentLoaded by nearly a full
second on our pages.
After the Facebook API has been loaded asynchronously, it executes
window.fbAsyncInit, which is where they suggest placing
code that depends on the
The answers on StackOverflow may work, but they feel inelegant. For
instance, one answer addresses this problem by setting a flag to true
fbAsyncInit callback, and creates a
fbEnsureInit method that uses a
recursive timeout to poll the flag.
We decided to take a different approach. Thankfully, the Facebook API sets up a
FB, for developers to interact with.
So we developed a class,
MethodProxy, to act as a proxy between the rest of
our code and the
FB object. It accepts an object to forward calls onto, and
it masquerades as an Array by implementing a
push method. The
accepts a single argument of a array whose first position is always a string of
the method name on the
FB object to be executed, followed by as many
arguments to be given to that method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
This allows us to initialize a native Array when the page loads to collect
calls to Facebook’s API. Then, in the
fbAsyncInit callback, we Indiana Jones
style swap out the native array with an instantiation of our
object, which then consumes the queued events by executing them on the
object. The end result is a consistent API for our code to use regardless of
the state of Facebook’s asynchronously loaded API.
1 2 3 4 5 6 7 8 9 10 11 12 13
MethodProxy is general enough to be used for other similar cases so we’ve
released it as method-proxy-js, an open source project under
the MIT license and packaged it up for
npm. Installing is as easy as