Top Banner
Improving 3rd Party Script Performance with <IFRAME>s Philip Tellis / [email protected] Boston Web Perf / 2013-10-22 Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 1
52

Improving 3rd Party Script Performance

May 18, 2015

Download

Technology

Philip Tellis

Learn how 3rd party script authors can make their scripts perform better and cause less trouble for host pages.

http://www.meetup.com/Web-Performance-Boston/events/143640602/
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Improving 3rd Party Script Performance

Improving 3rd Party Script Performance with<IFRAME>s

Philip Tellis / [email protected]

Boston Web Perf / 2013-10-22

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 1

Page 2: Improving 3rd Party Script Performance

• Philip Tellis• @bluesmoon• [email protected]• SOASTA

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 2

Page 3: Improving 3rd Party Script Performance

1Loading JavaScript

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 3

Page 4: Improving 3rd Party Script Performance

Do you use JavaScript?

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 4

Page 5: Improving 3rd Party Script Performance

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

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 5

Page 6: Improving 3rd Party Script Performance

<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

Page 7: Improving 3rd Party Script Performance

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 7

Page 8: Improving 3rd Party Script Performance

document.createElement("script");

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 8

Page 9: Improving 3rd Party Script Performance

dynamic script node

1 Loads in parallel with the rest of the page2 Still blocks the onload event3 No telling when it will load up

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 9

Page 10: Improving 3rd Party Script Performance

No telling when!

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 10

Page 11: Improving 3rd Party Script Performance

The Method Queue Pattern

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 11

Page 12: Improving 3rd Party Script Performance

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

Page 13: Improving 3rd Party Script Performance

MQP

var self = this;_mq = _mq || [];while(_mq.length) {

// remove the first item from the queuevar params = _mq.shift();// remove the method from the first itemvar method = params.shift();

self[method].apply(self, params);}

_mq.push = function(params) {// remove the method from the first itemvar method = params.shift();

self[method].apply(self, params);}

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 13

Page 14: Improving 3rd Party Script Performance

That takes care of #3

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 14

Page 15: Improving 3rd Party Script Performance

But we still block onload

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 15

Page 16: Improving 3rd Party Script Performance

IFRAMEs to the rescue

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 16

Page 17: Improving 3rd Party Script Performance

But IFRAMEs block onload until the subpage hasloaded

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 17

Page 18: Improving 3rd Party Script Performance

(This sub-page intentionally left blank)

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 18

Page 19: Improving 3rd Party Script Performance

So here’s the code – Section I

// Section 1 - Create the iframevar 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 hurtingscreenreaders)

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 19

Page 20: Improving 3rd Party Script Performance

javascript:false is key to solving mostcross-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

Page 21: Improving 3rd Party Script Performance

Except if the page developer setsdocument.domain

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 21

Page 22: Improving 3rd Party Script Performance

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 22

Page 23: Improving 3rd Party Script Performance

The code – Section II

// Section 2 - handle document.domaintry {

// sec exception if document.domain was setdoc = 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

Page 24: Improving 3rd Party Script Performance

Only set document.domain if it has alreadybeen set!

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 24

Page 25: Improving 3rd Party Script Performance

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

Page 26: Improving 3rd Party Script Performance

Notice that we’ve set document.domain again

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 26

Page 27: Improving 3rd Party Script Performance

This doesn’t work if document.domain is setafter our JavaScript loads

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 27

Page 28: Improving 3rd Party Script Performance

Inside this function, document is the parentdocument and this is the iframe!

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 28

Page 29: Improving 3rd Party Script Performance

Also, global variables inside _l() are global to theparent window

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 29

Page 30: Improving 3rd Party Script Performance

Modify the MQP for IFRAME support

GLOBAL = window;

// Running in an iframe, and our script node’s// id is js-iframe-asyncif(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

Page 31: Improving 3rd Party Script Performance

GLOBAL refers to the parent window and windowrefers to the iframe

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 31

Page 32: Improving 3rd Party Script Performance

So attach events to GLOBAL

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 32

Page 33: Improving 3rd Party Script Performance

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

Page 34: Improving 3rd Party Script Performance

Result: Happy Customers

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 34

Page 35: Improving 3rd Party Script Performance

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

Page 36: Improving 3rd Party Script Performance

2Cache Behaviour

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 36

Page 37: Improving 3rd Party Script Performance

We have boomerang set to be cached for 7 daysCache-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

Page 38: Improving 3rd Party Script Performance

how soon does a new version get to everyone?

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 38

Page 39: Improving 3rd Party Script Performance

hourly on weekends

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 39

Page 40: Improving 3rd Party Script Performance

hourly on weekdays

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 40

Page 41: Improving 3rd Party Script Performance

This is a problem if we have emergency fixes

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 41

Page 42: Improving 3rd Party Script Performance

Cache busting with a far-future expires header

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 42

Page 43: Improving 3rd Party Script Performance

Some more code...

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 43

Page 44: Improving 3rd Party Script Performance

location.reload(true);

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 44

Page 45: Improving 3rd Party Script Performance

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 proxiesand Firefox 3.5.11Note: 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

Page 46: Improving 3rd Party Script Performance

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

Page 47: Improving 3rd Party Script Performance

reloader.html can be cached forever

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 47

Page 48: Improving 3rd Party Script Performance

Other caching quirks

• Some proxies will ignore all cache control headers andnever clear their cache

• Some user agents have broken clocks, so expiry dateseither never occur or always occur

• Some versions of Chrome have a cache corruption bug sothey 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

Page 49: Improving 3rd Party Script Performance

Old but active versions of boomerang

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 49

Page 50: Improving 3rd Party Script Performance

And the blog post...

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

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 50

Page 51: Improving 3rd Party Script Performance

Thank You – Questions?

• Philip Tellis• @bluesmoon• [email protected]• www.SOASTA.com• boomerang• LogNormal Blog

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 51

Page 52: Improving 3rd Party Script Performance

Image Credits

• Neutraface Blocks! by David Joycehttp://www.flickr.com/photos/deapeajay/3913282801/

• Stop Hammertime by Rich Andersonhttp://www.flickr.com/photos/memestate/54408373/

• This Title Intentionally Left Blank by Jonathan Hinklehttp://www.flickr.com/photos/hynkle/4535749633/

• All other images taken at Velocity 2013 by Philip Tellis andshared under a Creative Commons Attribution-Share AlikeLicense.

Boston Web Perf / 2013-10-22 Improving 3rd Party Script Performance with <IFRAME>s 52