10. 1995: scripts in HEAD
<head>
<script src=‘a.js’></script>
</head>
blocks other downloads (IE 6-7, images
in IE, iframes)
downloaded sequentially (IE 6-7)
blocks rendering during download &
parse-execute
11. 2007: move scripts to bottom
...
<script src=‘a.js’></script>
</body>
doesn’t block other downloads
downloaded sequentially in IE 6-7
blocks rendering during download &
parse-execute
12. 2009: load scripts async
var se =
document.createElement(‘script’)
;
se.src = ‘a.js’;
document.getElementsByTagName(‘he
ad’)[0].appendChild(se);
doesn’t block other downloads
downloaded in parallel (all browsers)
blocks rendering during parse-execute
13. 2010: async + on-demand exec
var se = new Image(); // Object
se.onload = registerScript;
se.src = ‘a.js’;
separate download from parse-execute
doesn’t block other downloads
downloaded in parallel (all browsers)
doesn’t block rendering until demanded
15. script async & defer
parsing doesn’t wait for script:
• async – executed when available
• defer – executed when parsing finished
when is it downloaded?
missing:
• defer download AND execution
• async/defer download, execute on demand
16. 20??: markup
<script src=‘a.js’
[async|defer|noexecute]
[deferdownload]>
doesn’t block downloads
downloaded in parallel
doesn’t block rendering until demanded
doesn’t contend for a connection
easier
17. ControlJS
a JavaScript module for making scripts load faster
just change HTML
inline & external scripts
<script type=‘text/cjs’
data-cjssrc=‘main.js’>
</script>
<script type=‘text/cjs’>
var name = getName();
</script>
http://controljs.org/
18. ControlJS
a JavaScript module for making scripts load faster
download without executing
<script type=‘text/cjs’
data-cjssrc=‘main.js’
data-cjsexec=false>
<script>
Later if/when needed:
CJS.execScript(src);
19. GMail Mobile
<script type=‘text/javascript’>
/*
var ...
*/
</script>
get script DOM element's text
remove comments
eval() when invoked
awesome for prefetching JS that might
(not) be needed
http://goo.gl/l5ZLQ
23. Home screen apps on iPhone are slower
because resources are re-requested
even though they should be read from
cache.
24. localStorage
window.localStorage:
setItem()
getItem()
removeItem()
clear()
also sessionStorage
all popular browsers, 5MB max
http://dev.w3.org/html5/webstorage/
http://diveintohtml5.org/storage.html
25. localStorage as cache
1st doc: write JS & CSS blocks to localStorage
mres.-0yDUQJ03U8Hjija: <script>(function(){...
set cookie with entries & version
MRES=-0yDUQJ03U8Hjija:-4EaJoFuDoX0iloI:...
later docs: read JS & CSS from localStorage
document.write( localStorage.getItem(mres.-
0yDUQJ03U8Hjija) );
http://stevesouders.com/blog/2011/03/28/storager-case-
study-bing-google/
26. Google Analytics Async Snippet
var ga = document.createElement(‘script’);
ga.type = ‘text/javascript’;
ga.async = true;
ga.src = (‘https:’ ==
document.location.protocol ? ‘https://ssl’ :
‘http://www’)+‘.google-analytics.com/ga.js’;
var s =
document.getElementsByTagName(‘script’)[
0];
s.parentNode.insertBefore(ga, s);
code.google.com/apis/analytics/docs/tracking/asyncTracking.html
27. var ga = document.createElement(‘script’);
ga.type = ‘text/javascript’;
ga.async = true;
ga.src = (‘https:’ ==
document.location.protocol ? ‘https://ssl’ :
‘http://www’)+‘.google-analytics.com/ga.js’;
var s =
document.getElementsByTagName(‘script’)[
0];
s.parentNode.insertBefore(ga, s);
avoid mixed content warning
protocol relative URLs have problems
set src last
stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/
28. var ga = document.createElement(‘script’);
ga.type = ‘text/javascript’;
ga.async = true;
ga.src = (‘https:’ ==
document.location.protocol ? ‘https://ssl’ :
‘http://www’)+‘.google-analytics.com/ga.js’;
var s =
document.getElementsByTagName(‘script’)[
0];
s.parentNode.insertBefore(ga, s);
previously:
getElementsByTagName(‘head’)[0].
appendChild(ga)
HEAD might not exist
stevesouders.com/blog/2010/05/11/appendchild-vs-insertbefore/
Android 1.5, iPhone 3.0, Opera 8.50, Safari 3.2
stevesouders.com/blog/2010/05/12/autohead-my-first-browserscope-user-test/
29. var ga = document.createElement(‘script’);
ga.type = ‘text/javascript’;
ga.async = true;
ga.src = (‘https:’ ==
document.location.protocol ? ‘https://ssl’ :
‘http://www’)+‘.google-analytics.com/ga.js’;
var s =
document.getElementsByTagName(‘script’)[
0];
s.parentNode.insertBefore(ga, s);
some browsers preserve execution order
Firefox 3.6, Opera, OmniWeb
stevesouders.com/tests/jsorder.php
3.777 seconds - http://www.webpagetest.org/result/120111_0P_2TW4Q/ - block “.js” (it’s not downloaded)5.471 seconds - http://www.webpagetest.org/result/120111_GR_2TW90/Alexa top 100wwide
median: 3.650vs 2.4873.777 seconds - http://www.webpagetest.org/result/120111_0P_2TW4Q/ - block “.js” (it’s not downloaded)5.471 seconds - http://www.webpagetest.org/result/120111_GR_2TW90/Alexa top 100wwide
flickr.com/photos/gevertulley/4771808965/Generallyasync & defer scripts start downloading immediately. I wish they’d wait, esp. defer scripts, so they don’t hog connections from the limited pool.subatomic particle traces