200 likes | 444 Views
CS193H: High Performance Web Sites Lecture 20: Vol 2 – Don't Scatter Inline Scripts. Steve Souders Google souders@cs.stanford.edu. announcements. 11/17 – guest lecturer: Robert Johnson (Facebook), " Fast Data at Massive Scale - lessons learned at Facebook"
E N D
CS193H:High Performance Web SitesLecture 20: Vol 2 – Don't Scatter Inline Scripts Steve Souders Google souders@cs.stanford.edu
announcements 11/17 – guest lecturer: Robert Johnson (Facebook), "Fast Data at Massive Scale - lessons learned at Facebook" Handouts of Vol 2 chapters 1-4 are available in class and at office hours. Copies are being sent to SCPD students. DO NOT COPY OR DISTRIBUTE THESE HANDOUTS!
Load scripts without blocking follow-up from previous lecture: ads Google Analytics degrading script tags pattern – John Resig
ads and async scripts many ads load external scripts why can't these scripts be loaded using these non-blocking techniques? they use document.write if a script containing document.write is loaded asynchronously, the entire page is erased: http://stevesouders.com/tests/delayed-script-execution.php (click on "Load Dynamically") an alternative: Opera's "Delayed Script Execution"
Opera: Delayed Script Execution opera:config#Delayed%20Script%20Execution "Primarily for low bandwidth devices, not well-tested on desktop. Ignore script tags until entire document is parsed and rendered, then execute all scripts in order and re-render." renders page without blocking for script when script executes, document.write is performed where the script occurred good model for how SCRIPT DEFER should be implemented on all browsers blog post: http://www.stevesouders.com/blog/2008/09/11/delayed-script-execution-in-opera/
Google Analytics http://www.google.com/analytics/ "Learn more about where your visitors come from and how they interact with your site." case study: American Cancer Society http://www.cancer.org/ HTML code: <script type="text/javascript" src="http://www.google-analytics.com/ga.js"> </script> <script type="text/javascript"> vargaAcctNumber = "UA-144783-1"; varpageTracker = _gat._getTracker(gaAcctNumber); pageTracker._initData(); pageTracker._trackPageview </script> how load this asynchronously?
Google Analytics async IE IE: <script defer type="text/javascript" src='http://www.google-analytics.com/ga.js'> </script> <script type="text/javascript"> window.onload = function() { vargaAcctNumber = "UA-144783-1"; varpageTracker = _gat._getTracker(gaAcctNumber); pageTracker._initData(); pageTracker._trackPageview; } </script>
Google Analytics async FF Firefox: <script type="text/javascript"> var se = document.createElement('script'); se.src = 'http://www.google-analytics.com/ga.js'; document.getElementsByTagName('head')[0].appendChild(se); window.onload = function() { vargaAcctNumber = "UA-144783-1"; varpageTracker = _gat._getTracker(gaAcctNumber); pageTracker._initData(); pageTracker._trackPageview; } </script>
Google Analytics async other techniques: script in iframe 2 requests (iframe and ga.js) instead of 1 (ga.js) could try setting iframe's innerHTML (TBD) XHR eval and XHR injection different domains (www.google-analytics.com) document.write blocks other resources script DOM element for IE and FF add onreadystatechange handler instead of onload "degrading script tags" pattern – what's that?
Degrading Script Tags from John Resig blog post http://ejohn.org/blog/degrading-script-tags/ GA example: <script type="text/javascript" src="http://www.google-analytics.com/ga.js"> vargaAcctNumber = "UA-144783-1"; varpageTracker = _gat._getTracker(gaAcctNumber); pageTracker._initData(); pageTracker._trackPageview </script> no browser supports calling the inlined code instead, ga.js would be modified to call it...
Degrading Script Tags add to the end of the external script (eg, "ga.js"): var scripts = document.getElementsByTagName("script"); var cntr = scripts.length; while ( cntr ) { var curScript = scripts[cntr-1]; if (-1 != curScript.src.indexOf('ga.js')) { eval( curScript.innerHTML ); break; } cntr--; // why backwards? }
wrapping ga.js you can't modify ga.js proxy ga.js on your own server write cronjob to check ga.js Last-Modified update your proxied version when ga.js changes if you add versioning, you can give your vesion a far future Expires header (ga.js is 7 days)
Stylesheets – ensuring order Firefox 3 and IE download stylesheets in parallel with other resources http://stevesouders.com/cuzillion/?c0=hc1hfff2_0&c1=hc1hfff2_0&c2=bi1hfff2_0&c3=bf1hfff2_0&c4=bj1hfff2_0 stylesheets are parsed in the order specified, regardless of download order http://stevesouders.com/hpws2/stylesheets-order.php same for stylesheets and inline styles http://stevesouders.com/hpws2/css-order.php what about stylesheets and inline scripts?
Inline scripts block long executing inline scripts block rendering and downloads of everything after them in the page • http://stevesouders.com/cuzillion/?c0=bi1hfff1_0&c1=bb0hfff0_5&c2=bi1hfff1_0 workarounds: initiate execution with setTimeout (>250 for FF, nglayout.initialpaint.delay) move JavaScript to external script with advanced downloading techniques use Defer attribute (IE only)
Inline script parallelization resources that occur before an inline script download in parallel while the script executes http://stevesouders.com/cuzillion/?c0=bi1hfff2_0&c1=bb0hfff0_1&c2=bf2hfff2_0&c3=bb0hfff0_1&c4=bi3hfff2_0 ...except for stylesheets http://stevesouders.com/cuzillion/?c0=bc1hfff2_0&c1=bb0hfff0_1&c2=bc2hfff2_0&c3=bb0hfff0_1&c4=bi3hfff2_0 why?! CSS and JavaScript might have interdependencies how might this affect stylesheet and inline script download parallelization?
Stylesheet, inline script Block Downloading Firefox 3 and IE download stylesheets in parallel with other resources ...unless the stylesheet is followed by an inline script http://stevesouders.com/cuzillion/?ex=10021 best to move inline scripts above stylesheets or below other resources use Link, not @import @import allows the inline script to start and block in IE and FF2 • http://stevesouders.com/cuzillion/?c0=hc1hfff2_0&c1=hc1hfft2_0&c2=hb0hfff0_3&c3=hj1hfff2_0&t=1227048065109
Examples of Scattered Scripts MSN Wikipedia eBay MySpace
Don't Scatter Inline Scripts remember inline scripts carry a cost avoid long-executing inline scripts don't put inline scripts between stylesheets and other resources
Homework 12/1 11:59pm – Assignment #6 - Improving a Top Site rules 11-14 Vol 2: • Split the Initial Payload • Load Scripts Without Blocking • Don't Scatter Inline Scripts • Shard Dominant Domains • Optimize Images
Questions What happens if an external script loaded asynchronously does document.write? How can you load an external script asynchronously, and have an inline script execute as soon as the external script is loaded? What do inline scripts block? How can you workaround this blocking? What's the unusual behaviour of a stylesheet, inline script, and image (in that order)? What would explain why browser developers implemented this behaviour? How does @import cause downloading problems with stylesheets followed by inline scripts?