5. <script src>
• Works well with browser lookahead
• But blocks everything
• Yes, you can use async or defer
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 5
6. Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 6
7. Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 7
9. dynamic script node
1 Loads in parallel with the rest of the page
2 Still blocks the onload event
3 No telling when it will load up
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 9
10. The Method Queue Pattern
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 10
11. MQP
var _mq = _mq || [];
var s = document.createElement("script"),
t = document.getElementsByTagName("script")[0];
s.src="http://some.site.com/script.js";
t.parentNode.insertBefore(s, t);
// script.js will be available some time in the
// future, but we can call its methods
_mq.push(["method1", list, of, params]);
_mq.push(["method2", other, params]);
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 11
12. MQP
var self = this;
_mq = _mq || [];
while(_mq.length) {
// remove the first item from the queue
var params = _mq.shift();
// remove the method from the first item
var method = params.shift();
self[method].apply(self, params);
}
_mq.push = function(params) {
// remove the method from the first item
var method = params.shift();
self[method].apply(self, params);
}
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 12
13. That takes care of #3
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 13
14. But we still block onload
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 14
15. IFRAMEs to the rescue
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 15
16. But IFRAMEs block onload until the subpage has
loaded
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 16
17. (This sub-page intentionally left blank)
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 17
18. So here’s the code – Section I
// Section 1 - Create the iframe
var dom,doc,where,
iframe = document.createElement("iframe");
iframe.src = "javascript:false";
(iframe.frameElement || iframe).style.cssText =
"width: 0; height: 0; border: 0";
where = document.getElementsByTagName("script");
where = where[where.length - 1];
where.parentNode.insertBefore(iframe, where);
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 18
19. javascript:false is key to solving most
cross-domain issues
Ask me about about:blank
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 19
20. Except if the page developer sets
document.domain
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 20
21. Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 21
22. The code – Section II
// Section 2 - handle document.domain
try {
doc = iframe.contentWindow.document;
}
catch(e) {
dom = document.domain;
iframe.src =
"javascript:var d=document.open();" +
"d.domain=’" + dom + "’;" +
"void(0);";
doc = iframe.contentWindow.document;
}
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 22
23. Only set document.domain if it has already
been set!
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 23
24. The code – Section III
// Section 3 - tell the iframe to load our script
doc.open()._l = function() {
var js = this.createElement("script");
if(dom)
this.domain = dom;
js.id = "js-iframe-async";
js.src = script_url;
this.body.appendChild(js);
};
doc.write(’<body onload="document._l();">’);
doc.close();
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 24
25. Notice that we’ve set document.domain again
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 25
26. Inside this function, document is the parent
document and this is the iframe!
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 26
27. Also, global variables inside _l() are global to the
parent window
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 27
28. Modify the MQP for IFRAME support
GLOBAL = window;
// Running in an iframe, and our script node’s
// id is js-iframe-async
if(window.parent != window &&
document.getElementById("js-iframe-async")) {
GLOBAL = window.parent;
}
GLOBAL._mq = GLOBAL._mq || [];
_mq = GLOBAL._mq;
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 28
29. GLOBAL refers to the parent window and window
refers to the iframe
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 29
30. So attach events to GLOBAL
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 30
31. Summary
• Create an iframe with src set to javascript:false
• Set document.domain if needed (twice)
• Write dynamic script node into iframe on iframe’s onload
event
• Alias parent window into iframe
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 31
33. Read all about it
• http://lognormal.com/blog/2012/12/12/the-script-loader-
pattern/
• https://www.w3.org/Bugs/Public/show_bug.cgi?id=21074
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 33
34. Cache busting with a far-future expires header
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 34
37. More completely
<script src="SCRIPT.js"></script>
<script>
var reqd_ver = location.search;
window.onload = function() {
var ver = SCRIPT.version;
if (ver < reqd_ver) {
location.reload(true);
}
};
</script>
The condition protects us from an infinite loop with bad proxies
and Firefox 3.5.11
Note: Don’t use location.hash – it messes with history on IE8.
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 37
38. And the blog post...
http://www.lognormal.com/blog/2012/06/17/more-
on-updating-boomerang/
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 38
39. Join us right after this guy...
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 39
40. Revolutionary RUM
1 Combine 1oz Cane Rum, 3/4oz Blood Orange Puree, &
1/2oz citrus infused syrup in a mixing glass
2 Add ice and shake vigourously
3 Strain into a chilled cocktail glass
4 Top with lime-mint foam
17:45, Evolution Café + Bar, Hyatt Lobby
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 40
41. • Philip Tellis
• @bluesmoon
• philip@bluesmoon.info
• www.SOASTA.com
• boomerang
• LogNormal Blog
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 41
42. Image Credits
• Stop Hammertime by Rich Anderson
http://www.flickr.com/photos/memestate/54408373/
• Nicholas Zakas by Ben Alman
http://www.flickr.com/photos/rj3/5635837522/
Velocity 2013 / 2013-06-20 Improving 3rd Party Script Performance with <IFRAME>s 42