SlideShare une entreprise Scribd logo
1  sur  52
Télécharger pour lire hors ligne
Improving 3rd Party Script Performance with
<IFRAME>s
Philip Tellis / ptellis@soasta.com

Boston Web Perf / 2013-10-22

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

1
• Philip Tellis
• @bluesmoon
• philip@bluesmoon.info
• SOASTA

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

2
1

Loading JavaScript

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

3
Do you use JavaScript?

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

4
<script src="..."></script>

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

5
<script src>

• Works well with browser lookahead
• But blocks everything
• Yes, you can use async or defer

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

6
Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

7
document.createElement("script");

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

8
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

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

9
No telling when!

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

10
The Method Queue Pattern

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

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]);

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

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);
}
Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

13
That takes care of #3

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

14
But we still block onload

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

15
IFRAMEs to the rescue

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

16
But IFRAMEs block onload until the subpage has
loaded

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

17
(This sub-page intentionally left blank)

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

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.title = ""; iframe.role = "presentation";
(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);
(Note that we set iframe.title and iframe.role to avoid hurting
screenreaders)
Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

19
javascript:false is key to solving most
cross-domain issues

about:blank is problematic on IE6 with SSL

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

20
Except if the page developer sets
document.domain

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

21
Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

22
The code – Section II

// Section 2 - handle document.domain
try {
// sec exception if document.domain was set
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;
}

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

23
Only set document.domain if it has already
been set!

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

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();

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

25
Notice that we’ve set document.domain again

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

26
This doesn’t work if document.domain is set
after our JavaScript loads

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

27
Inside this function, document is the parent
document and this is the iframe!

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

28
Also, global variables inside _l() are global to the
parent window

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

29
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;

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

30
GLOBAL refers to the parent window and window
refers to the iframe

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

31
So attach events to GLOBAL

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

32
Summary (part 1)

• 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

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

33
Result: Happy Customers

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

34
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

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

35
2

Cache Behaviour

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

36
We have boomerang set to be cached for 7 days
Cache-Control:

max-age=604800,

stale-while-revalidate=60, stale-if-error=3600

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

37
how soon does a new version get to everyone?

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

38
hourly on weekends

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

39
hourly on weekdays

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

40
This is a problem if we have emergency fixes

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

41
Cache busting with a far-future expires header

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

42
Some more code...

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

43
location.reload(true);

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

44
More completely
<script src="SCRIPT.js"></script>
<script>
var reqd_ver = location.search;
window.onload = function() {
var ver = SCRIPT.version;
if (ver < reqd_ver) { // or use semver
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.
Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

45
Add this in an iframe after onload using
//url.to/reloader.html?1.2.3

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

46
reloader.html can be cached forever

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

47
Other caching quirks

• Some proxies will ignore all cache control headers and

never clear their cache
• Some user agents have broken clocks, so expiry dates

either never occur or always occur
• Some versions of Chrome have a cache corruption bug so

they might start up with an empty cache
• Cache-control headers are honoured by pre-browsing

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

48
Old but active versions of boomerang

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

49
And the blog post...

http://www.lognormal.com/blog/2012/06/17/moreon-updating-boomerang/

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

50
Thank You – Questions?

• Philip Tellis
• @bluesmoon
• philip@bluesmoon.info
• www.SOASTA.com
• boomerang
• LogNormal Blog

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

51
Image Credits

• Neutraface Blocks! by David Joyce
http://www.flickr.com/photos/deapeajay/3913282801/
• Stop Hammertime by Rich Anderson
http://www.flickr.com/photos/memestate/54408373/
• This Title Intentionally Left Blank by Jonathan Hinkle
http://www.flickr.com/photos/hynkle/4535749633/
• All other images taken at Velocity 2013 by Philip Tellis and
shared under a Creative Commons Attribution-Share Alike
License.

Boston Web Perf / 2013-10-22

Improving 3rd Party Script Performance with <IFRAME>s

52

Contenu connexe

En vedette (7)

Salvador da Bahia
Salvador da BahiaSalvador da Bahia
Salvador da Bahia
 
Urbanização do Brasil
Urbanização do BrasilUrbanização do Brasil
Urbanização do Brasil
 
Urbanização conceitos
Urbanização conceitosUrbanização conceitos
Urbanização conceitos
 
Geomorfologia Geral e do Brasil
Geomorfologia Geral e do BrasilGeomorfologia Geral e do Brasil
Geomorfologia Geral e do Brasil
 
Urbanização, rede urbana e metrópoles
Urbanização, rede urbana e metrópolesUrbanização, rede urbana e metrópoles
Urbanização, rede urbana e metrópoles
 
Urbanizacao
UrbanizacaoUrbanizacao
Urbanizacao
 
Urbanização brasileira
Urbanização brasileiraUrbanização brasileira
Urbanização brasileira
 

Plus de Philip Tellis

Improving 3rd Party Script Performance With IFrames
Improving 3rd Party Script Performance With IFramesImproving 3rd Party Script Performance With IFrames
Improving 3rd Party Script Performance With IFrames
Philip Tellis
 
Analysing network characteristics with JavaScript
Analysing network characteristics with JavaScriptAnalysing network characteristics with JavaScript
Analysing network characteristics with JavaScript
Philip Tellis
 
A Node.JS bag of goodies for analyzing Web Traffic
A Node.JS bag of goodies for analyzing Web TrafficA Node.JS bag of goodies for analyzing Web Traffic
A Node.JS bag of goodies for analyzing Web Traffic
Philip Tellis
 

Plus de Philip Tellis (20)

Improving D3 Performance with CANVAS and other Hacks
Improving D3 Performance with CANVAS and other HacksImproving D3 Performance with CANVAS and other Hacks
Improving D3 Performance with CANVAS and other Hacks
 
Frontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy PersonFrontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy Person
 
Frontend Performance: De débutant à Expert à Fou Furieux
Frontend Performance: De débutant à Expert à Fou FurieuxFrontend Performance: De débutant à Expert à Fou Furieux
Frontend Performance: De débutant à Expert à Fou Furieux
 
Frontend Performance: Expert to Crazy Person
Frontend Performance: Expert to Crazy PersonFrontend Performance: Expert to Crazy Person
Frontend Performance: Expert to Crazy Person
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level Metrics
 
Frontend Performance: Beginner to Expert to Crazy Person (San Diego Web Perf ...
Frontend Performance: Beginner to Expert to Crazy Person (San Diego Web Perf ...Frontend Performance: Beginner to Expert to Crazy Person (San Diego Web Perf ...
Frontend Performance: Beginner to Expert to Crazy Person (San Diego Web Perf ...
 
Frontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy PersonFrontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy Person
 
Frontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy PersonFrontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy Person
 
Frontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy PersonFrontend Performance: Beginner to Expert to Crazy Person
Frontend Performance: Beginner to Expert to Crazy Person
 
mmm... beacons
mmm... beaconsmmm... beacons
mmm... beacons
 
RUM Distillation 101 -- Part I
RUM Distillation 101 -- Part IRUM Distillation 101 -- Part I
RUM Distillation 101 -- Part I
 
Improving 3rd Party Script Performance With IFrames
Improving 3rd Party Script Performance With IFramesImproving 3rd Party Script Performance With IFrames
Improving 3rd Party Script Performance With IFrames
 
Extending Boomerang
Extending BoomerangExtending Boomerang
Extending Boomerang
 
Abusing JavaScript to measure Web Performance, or, "how does boomerang work?"
Abusing JavaScript to measure Web Performance, or, "how does boomerang work?"Abusing JavaScript to measure Web Performance, or, "how does boomerang work?"
Abusing JavaScript to measure Web Performance, or, "how does boomerang work?"
 
The Statistics of Web Performance Analysis
The Statistics of Web Performance AnalysisThe Statistics of Web Performance Analysis
The Statistics of Web Performance Analysis
 
Abusing JavaScript to Measure Web Performance
Abusing JavaScript to Measure Web PerformanceAbusing JavaScript to Measure Web Performance
Abusing JavaScript to Measure Web Performance
 
Rum for Breakfast
Rum for BreakfastRum for Breakfast
Rum for Breakfast
 
Analysing network characteristics with JavaScript
Analysing network characteristics with JavaScriptAnalysing network characteristics with JavaScript
Analysing network characteristics with JavaScript
 
A Node.JS bag of goodies for analyzing Web Traffic
A Node.JS bag of goodies for analyzing Web TrafficA Node.JS bag of goodies for analyzing Web Traffic
A Node.JS bag of goodies for analyzing Web Traffic
 
Input sanitization
Input sanitizationInput sanitization
Input sanitization
 

Dernier

Dernier (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 

Improving 3rd Party Script Performance

  • 1. Improving 3rd Party Script Performance with <IFRAME>s Philip Tellis / ptellis@soasta.com Boston Web Perf / 2013-10-22 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 1
  • 2. • Philip Tellis • @bluesmoon • philip@bluesmoon.info • SOASTA Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 2
  • 3. 1 Loading JavaScript Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 3
  • 4. Do you use JavaScript? Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 4
  • 5. <script src="..."></script> Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 5
  • 6. <script src> • Works well with browser lookahead • But blocks everything • Yes, you can use async or defer Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 6
  • 7. Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 7
  • 8. document.createElement("script"); Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 8
  • 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 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 9
  • 10. No telling when! Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 10
  • 11. The Method Queue Pattern Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 11
  • 12. 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]); Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 12
  • 13. 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); } Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 13
  • 14. That takes care of #3 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 14
  • 15. But we still block onload Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 15
  • 16. IFRAMEs to the rescue Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 16
  • 17. But IFRAMEs block onload until the subpage has loaded Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 17
  • 18. (This sub-page intentionally left blank) Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 18
  • 19. 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.title = ""; iframe.role = "presentation"; (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); (Note that we set iframe.title and iframe.role to avoid hurting screenreaders) Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 19
  • 20. javascript:false is key to solving most cross-domain issues about:blank is problematic on IE6 with SSL Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 20
  • 21. Except if the page developer sets document.domain Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 21
  • 22. Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 22
  • 23. The code – Section II // Section 2 - handle document.domain try { // sec exception if document.domain was set 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; } Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 23
  • 24. Only set document.domain if it has already been set! Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 24
  • 25. 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(); Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 25
  • 26. Notice that we’ve set document.domain again Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 26
  • 27. This doesn’t work if document.domain is set after our JavaScript loads Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 27
  • 28. Inside this function, document is the parent document and this is the iframe! Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 28
  • 29. Also, global variables inside _l() are global to the parent window Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 29
  • 30. 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; Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 30
  • 31. GLOBAL refers to the parent window and window refers to the iframe Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 31
  • 32. So attach events to GLOBAL Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 32
  • 33. Summary (part 1) • 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 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 33
  • 34. Result: Happy Customers Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 34
  • 35. 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 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 35
  • 36. 2 Cache Behaviour Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 36
  • 37. We have boomerang set to be cached for 7 days Cache-Control: max-age=604800, stale-while-revalidate=60, stale-if-error=3600 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 37
  • 38. how soon does a new version get to everyone? Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 38
  • 39. hourly on weekends Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 39
  • 40. hourly on weekdays Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 40
  • 41. This is a problem if we have emergency fixes Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 41
  • 42. Cache busting with a far-future expires header Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 42
  • 43. Some more code... Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 43
  • 44. location.reload(true); Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 44
  • 45. More completely <script src="SCRIPT.js"></script> <script> var reqd_ver = location.search; window.onload = function() { var ver = SCRIPT.version; if (ver < reqd_ver) { // or use semver 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. Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 45
  • 46. Add this in an iframe after onload using //url.to/reloader.html?1.2.3 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 46
  • 47. reloader.html can be cached forever Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 47
  • 48. Other caching quirks • Some proxies will ignore all cache control headers and never clear their cache • Some user agents have broken clocks, so expiry dates either never occur or always occur • Some versions of Chrome have a cache corruption bug so they might start up with an empty cache • Cache-control headers are honoured by pre-browsing Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 48
  • 49. Old but active versions of boomerang Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 49
  • 50. And the blog post... http://www.lognormal.com/blog/2012/06/17/moreon-updating-boomerang/ Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 50
  • 51. Thank You – Questions? • Philip Tellis • @bluesmoon • philip@bluesmoon.info • www.SOASTA.com • boomerang • LogNormal Blog Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 51
  • 52. Image Credits • Neutraface Blocks! by David Joyce http://www.flickr.com/photos/deapeajay/3913282801/ • Stop Hammertime by Rich Anderson http://www.flickr.com/photos/memestate/54408373/ • This Title Intentionally Left Blank by Jonathan Hinkle http://www.flickr.com/photos/hynkle/4535749633/ • All other images taken at Velocity 2013 by Philip Tellis and shared under a Creative Commons Attribution-Share Alike License. Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 52