Hi guys,
I just stumbled upon a problem with our Facebook integration on our mobile marketplace Officialbrands T-Shirts | Unique Designs | Spreadshirt. And as Facebook seemed to have problems yesterday (December 2cd, 2015) in the United States, we seemed to have problems too. Although we integrated their Javascript using the async annotation (Can I use... Support tables for HTML5, CSS3, etc).
Anyway, I tried to reproduce the problem using WebPagetest and the SPOF feature with Chrome browser on Dulles, emulate mobile feature enabled and a SPOF configured to connect.facebook.net. And I was able to reproduce the issue (see http://www.webpagetest.org/result/151203_ZH_11N7/).
I still ask myself, whether this is really a problem, or whether the used Chrome browser or WebPagetest maybe just ignores the async annotation. Can you clarify that please?
Thanks for your help.
Cheers,
Martin
Hmm. I can’t figure out why but all of the browsers seem to be blocking and as best as I can tell the async script is about as async as it gets (both by dynamically attaching the script element and by having the async=true bit set).
WebPageTest just runs the browsers as they would normally run and Chrome should be honoring the async attribute (and anyway treat it as async since it attached).
FWIW, it also reproduces in Firefox: http://www.webpagetest.org/result/151203_22_1e9a37fd6f67a710cca9cee73248604c/
I tried using dev tools timelines to see in case maybe there was another script was using document.write or something ugly but it didn’t look like that was the case.
As far as I can tell, it’s a real issue and something related to how it is embedded in the page. Just can’t tell why yet.
Patrick,
thanks for the quick reply! I just wanted to make sure that my observation is correct. I will look into this tomorrow with one of our frontend devs. If we find out what we did wrong, I will post it here.
Cheers,
Martin
Patrick,
we found the solution on the Facebook blog.
Instead of integration the Facebook script via an async script
(function () {
var e = document.createElement('script');
e.async = true;
e.src = '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
we need to integrate it via an iframe to really have it run asynchronously and non render blocking.
(function() {
var url = '//connect.facebook.net/en_US/all.js';
var iframe = document.createElement('iframe');
(iframe.frameElement || iframe).style.cssText = "width: 0; height: 0; border: 0";
iframe.src = "javascript:false";
document.getElementById('fb-root').appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open().write('<body onload="'+
'window.inDapIF = true;' +
'var js = document.createElement(\'script\');'+
'js.src = \''+ url +'\';'+
'document.body.appendChild(js);">');
doc.close();
}());
Cheers,
Martin
The iframe technique should bake it not block the page onload event but the async script shouldn’t block page render/loading the way it was. Still very bizarre.