Successfully reported this slideshow.
Fast Loading JavaScript http://www.flickr.com/photos/gaelenh/1443926963/ Velocity EU 2011, @aaronpeters
Better performance ==  More revenues Revisorweb
“ I totally rock the house!” http://www.flickr.com/photos/jkohen/3799706725/
The problem
JavaScript blocks
Lots of JS blocks even more Torstein Frogner
Lots of JS blocks even more Torstein Frogner <script src=“file.js”> blocks parallel downloading in IE8 and Chrome (!) can’...
http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS
http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS
http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS Wanna see the horror?
It’s not getting any better
Requirements
load JS in a non-blocking way 1 scripts execute in order 2 couple external JS with inline JS 3 rendering starts soon; is p...
diskdepot.co.uk You want to be in control
Reduce risk to a minimum http://www.flickr.com/photos/48329209@N03/4430804547/
Create the best user experience! http://www.flickr.com/photos/97469566@N00/4848627841
Async FTW! http://www.flickr.com/photos/15181848@N02/3742832809
JavaScript Loading Techniques
Normal Script Src <ul><li><script  src =“foo.js&quot; ></script> </li></ul><script  src =“bar.js&quot; ></script> <script>...
Normal Script Src Chrome’s silly preload logic
Chrome’s silly preload logic (CSPL) If there is a non-DEFER, non-ASYNC parser-inserted script in <head>, Chrome (15) only ...
CSPL - Proof in <head> in <body>
Browserscope doesn’t tell you Browserscope testpage has script in <body>
Same in IE9? Nope, all good!
How about FF7? Yeah, good too!
Why CSPL is a problem Other objects start downloading late It’s against developer intent: bottom BODY means “do it last, o...
Solutions for CSPL Move to top of <body> Move to bottom of <body> Inline the code Add DEFER attribute Add ASYNC attribute ...
<ul><li>Pre-render blocking JS? </li></ul><ul><li>Inline in  <head> </li></ul><ul><li>External file top of  <body> </li></...
Script Insertion <ul><li><script> </li></ul><ul><li>var  d=document, js=d.createElement( 'script' ), </li></ul><ul><li>el=...
Script Insertion Important! script can’t have  document.write
Script Insertion + callback() <ul><li><script> </li></ul><ul><li>function  exec() { renderThingy(); } </li></ul><ul><li>va...
Script insertion is awesome. Make it your default 2 http://www.flickr.com/photos/valeriebb/290711738/
DEFER attribute <ul><li><script  defer   src =“framework.js&quot; ></script> </li></ul><script  defer   src =“app.js&quot;...
DEFER attribute Important! script can’t have  document.write
DEFER & jQuery in IE <ul><li><script  defer   src =“jquery.js&quot; ></script> </li></ul><script  defer   src =“jquery-plu...
Combine jquery.js and jquery-dependent.js if you want  DEFER 2 http://www.flickr.com/photos/valeriebb/290711738/
ASYNC attribute <ul><li><script  async   src =“file.js&quot; ></script> </li></ul>
ASYNC attribute Important! script can’t have  document.write
Only use  async   as an ‘add-on ’ in dynamic insertion technique 3 http://www.flickr.com/photos/valeriebb/290711738/
ASYNC = false <ul><li><script> </li></ul><ul><li>var  d=document, js=d.createElement( 'script' ), </li></ul><ul><li>el=d.g...
ASYNC = false Important! script can’t have  document.write
Forget about  async=false It’s for the far future. 4 http://www.flickr.com/photos/valeriebb/290711738/
LABjs <ul><li><script> </li></ul><ul><li>$LAB </li></ul><ul><li>.script( &quot;framework.js&quot; ).wait() </li></ul><ul><...
LABjs Important! script can’t have  document.write
Script loaders like LABjs can be your best friend. Try it! 5 http://www.flickr.com/photos/valeriebb/290711738/
Execute before Start Render? <2k gzipped? Inline, in <head> Y Couple with inline script? Preserve exec order? N Using jQue...
Somewhat off-topic statements <ul><li>Don’t load it if the page doesn’t need it ! </li></ul><ul><li>Don’t use jQuery for e...
Third Party JavaScript
Social buttons BFF! <!-- facebook like --> <div  class = &quot;fb-like&quot;   data-send= &quot;false&quot;   data-width= ...
Social buttons BFF! <!-- facebook like --> <div  class = &quot;fb-like&quot;   data-send= &quot;false&quot;   data-width= ...
Twitter Anywhere Tweet Box <ul><li><div  id =“tbox&quot; ></script> </li></ul><ul><li><script> </li></ul><ul><li>twttr.any...
You? Join the WPO community! You? You? You? You?
<ul><li>#webperf http://twitter.com/search#webperf </li></ul><ul><li>#WPOchat http://www.wpochat.org </li></ul><ul><li>Per...
http://www.flickr.com/photos/27282406@N03/4134166721/
Questions? http://www.flickr.com/photos/f-oxymoron/5005146417/
Upcoming SlideShare
Loading in …5
×

Fast Loading JavaScript

27,442 views

Published on

An walk-through of several JavaScript loading techniques with a characteristics table for each and at the end a decision tree to help you decide which technique to use.
Also, Chrome's silly preload logic!

Published in: Technology, Education

Fast Loading JavaScript

  1. Fast Loading JavaScript http://www.flickr.com/photos/gaelenh/1443926963/ Velocity EU 2011, @aaronpeters
  2. Better performance == More revenues Revisorweb
  3. “ I totally rock the house!” http://www.flickr.com/photos/jkohen/3799706725/
  4. The problem
  5. JavaScript blocks
  6. Lots of JS blocks even more Torstein Frogner
  7. Lots of JS blocks even more Torstein Frogner <script src=“file.js”> blocks parallel downloading in IE8 and Chrome (!) can’t download subsequent images/iframes … has “silly preload logic” 2 <script src=“file.js”> and inline scripts block HTML parsing & page rendering 1
  8. http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS
  9. http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS
  10. http://www.flickr.com/photos/frenkieb/4423393/ Example of bad, bad JS Wanna see the horror?
  11. It’s not getting any better
  12. Requirements
  13. load JS in a non-blocking way 1 scripts execute in order 2 couple external JS with inline JS 3 rendering starts soon; is progressive 5 DOM ready fires asap 4
  14. diskdepot.co.uk You want to be in control
  15. Reduce risk to a minimum http://www.flickr.com/photos/48329209@N03/4430804547/
  16. Create the best user experience! http://www.flickr.com/photos/97469566@N00/4848627841
  17. Async FTW! http://www.flickr.com/photos/15181848@N02/3742832809
  18. JavaScript Loading Techniques
  19. Normal Script Src <ul><li><script src =“foo.js&quot; ></script> </li></ul><script src =“bar.js&quot; ></script> <script> // dependent on bar.js executeAfterBar(); </script>
  20. Normal Script Src Chrome’s silly preload logic
  21. Chrome’s silly preload logic (CSPL) If there is a non-DEFER, non-ASYNC parser-inserted script in <head>, Chrome (15) only preloads other parser-inserted scripts from <body>, not images!
  22. CSPL - Proof in <head> in <body>
  23. Browserscope doesn’t tell you Browserscope testpage has script in <body>
  24. Same in IE9? Nope, all good!
  25. How about FF7? Yeah, good too!
  26. Why CSPL is a problem Other objects start downloading late It’s against developer intent: bottom BODY means “do it last, other stuff comes first”
  27. Solutions for CSPL Move to top of <body> Move to bottom of <body> Inline the code Add DEFER attribute Add ASYNC attribute Use Script Insertion Keeps blocking Start Render
  28. <ul><li>Pre-render blocking JS? </li></ul><ul><li>Inline in <head> </li></ul><ul><li>External file top of <body> </li></ul>1 http://www.flickr.com/photos/valeriebb/290711738/
  29. Script Insertion <ul><li><script> </li></ul><ul><li>var d=document, js=d.createElement( 'script' ), </li></ul><ul><li>el=d.getElementsByTagName( 'script' )[ 0 ]; </li></ul><ul><li>js.src= “file.js&quot; ; </li></ul><ul><li>el.parentNode.insertBefore(js,el); </li></ul><ul><li></script> </li></ul>
  30. Script Insertion Important! script can’t have document.write
  31. Script Insertion + callback() <ul><li><script> </li></ul><ul><li>function exec() { renderThingy(); } </li></ul><ul><li>var d=document, js=d.createElement( 'script' ), </li></ul><ul><li>el=d.getElementsByTagName( 'script' )[ 0 ]; </li></ul><ul><li>js.src= “getsatisfaction.js“ ; </li></ul><ul><li>js.done=false; </li></ul><ul><li>js.onload=function(){ js.done=true,exec() }, </li></ul><ul><li>js.onreadystatechange=function(){ </li></ul><ul><li>(&quot;loaded&quot;===js.readyState||&quot;complete&quot;===js.readyState </li></ul><ul><li>) && !js.done && (js.done=true,exec())}; </li></ul><ul><li>el.parentNode.insertBefore(js,el); </li></ul><ul><li></script> </li></ul>
  32. Script insertion is awesome. Make it your default 2 http://www.flickr.com/photos/valeriebb/290711738/
  33. DEFER attribute <ul><li><script defer src =“framework.js&quot; ></script> </li></ul><script defer src =“app.js&quot; ></script> <script> // dependent on app.js initApp(); </script>
  34. DEFER attribute Important! script can’t have document.write
  35. DEFER & jQuery in IE <ul><li><script defer src =“jquery.js&quot; ></script> </li></ul><script defer src =“jquery-plugin.js&quot; ></script> ‘ jQuery’ is undefined
  36. Combine jquery.js and jquery-dependent.js if you want DEFER 2 http://www.flickr.com/photos/valeriebb/290711738/
  37. ASYNC attribute <ul><li><script async src =“file.js&quot; ></script> </li></ul>
  38. ASYNC attribute Important! script can’t have document.write
  39. Only use async as an ‘add-on ’ in dynamic insertion technique 3 http://www.flickr.com/photos/valeriebb/290711738/
  40. ASYNC = false <ul><li><script> </li></ul><ul><li>var d=document, js=d.createElement( 'script' ), </li></ul><ul><li>el=d.getElementsByTagName( 'script' )[ 0 ]; </li></ul><ul><li>js.async= false ; </li></ul><ul><li>js.src= “file.js&quot; ; </li></ul><ul><li>el.parentNode.insertBefore(js,el); </li></ul><ul><li></script> </li></ul><script async =“false” src =“file.js&quot; ></script>
  41. ASYNC = false Important! script can’t have document.write
  42. Forget about async=false It’s for the far future. 4 http://www.flickr.com/photos/valeriebb/290711738/
  43. LABjs <ul><li><script> </li></ul><ul><li>$LAB </li></ul><ul><li>.script( &quot;framework.js&quot; ).wait() </li></ul><ul><li>.script( &quot;plugin.framework.js&quot; ) </li></ul><ul><li>.wait( function (){ </li></ul><ul><li>myplugin.init(); </li></ul><ul><li>framework.init(); </li></ul><ul><li>}); </li></ul><ul><li></script> </li></ul><script src =“LABjs.js&quot; ></script>
  44. LABjs Important! script can’t have document.write
  45. Script loaders like LABjs can be your best friend. Try it! 5 http://www.flickr.com/photos/valeriebb/290711738/
  46. Execute before Start Render? <2k gzipped? Inline, in <head> Y Couple with inline script? Preserve exec order? N Using jQuery? Combine jquery.js & jquery-dependent.js Other script loaders, like Yepnope, may do an equally good job Y N Normal Script Src, top of <body> Y LABjs Y Dynamic insertion N DEFER Y N Execute right before DCL? N
  47. Somewhat off-topic statements <ul><li>Don’t load it if the page doesn’t need it ! </li></ul><ul><li>Don’t use jQuery for everything </li></ul><ul><li>Do waterfall chart analysis ,‘till you drop </li></ul><ul><ul><li>Use Webpagetest.org (Firefox 7 coming soon to all nodes!) </li></ul></ul><ul><ul><li>On WPT, use Video capturing to see how it renders </li></ul></ul><ul><ul><li>WPT has lots of useful commands in the API. Use them! </li></ul></ul>
  48. Third Party JavaScript
  49. Social buttons BFF! <!-- facebook like --> <div class = &quot;fb-like&quot; data-send= &quot;false&quot; data-width= &quot;280&quot; ></div> <!-- twitter --> <a class = &quot;twitter-share-button&quot; data-count= &quot;horizontal&quot; >Tweet</a> <!-- g+ --> <div class =&quot;g-plusone&quot; data-size= &quot;medium&quot; ></div> http://www.phpied.com/social-button-bffs/
  50. Social buttons BFF! <!-- facebook like --> <div class = &quot;fb-like&quot; data-send= &quot;false&quot; data-width= &quot;280&quot; ></div> <!-- twitter --> <a class = &quot;twitter-share-button&quot; data-count= &quot;horizontal&quot; >Tweet</a> <!-- g+ --> <div class =&quot;g-plusone&quot; data-size= &quot;medium&quot; ></div> http://www.phpied.com/social-button-bffs/ <div id =&quot;fb-root&quot; ></div ><!-- fb needs this --> <script >( function (d, s) { var js, fjs = d.getElementsByTagName(s)[ 0 ], load = function(url, id) { if (d.getElementById(id)) { return ;} js = d.createElement(s); js.async = js.src = url; js.id = id; fjs.parentNode.insertBefore(js, fjs); }; load( '//connect.facebook.net/en_US/all.js#xfbml=1', 'fbjssdk' ); load( 'https://apis.google.com/js/plusone.js' , 'gplus1js' ); load( '//platform.twitter.com/widgets.js', 'tweetjs' ); }(document, 'script' )); </script>
  51. Twitter Anywhere Tweet Box <ul><li><div id =“tbox&quot; ></script> </li></ul><ul><li><script> </li></ul><ul><li>twttr.anywhere( function (T) { </li></ul><ul><li>T( &quot;#tbox&quot; ).tweetBox(); </li></ul><ul><li>}); </li></ul><ul><li></script> </li></ul><ul><li></body> </li></ul>view-source:http://www.cdnplanet.com > jsbeautifier.org ... <script src=&quot;http://platform.twitter.com/anywhere.js?id=YOUR_API_KEY&v=1&quot;></script> </head> ...
  52. You? Join the WPO community! You? You? You? You?
  53. <ul><li>#webperf http://twitter.com/search#webperf </li></ul><ul><li>#WPOchat http://www.wpochat.org </li></ul><ul><li>Perfplanet http://perfplanet.com </li></ul><ul><li>Meetup http://web-performance.meetup.com/ </li></ul>
  54. http://www.flickr.com/photos/27282406@N03/4134166721/
  55. Questions? http://www.flickr.com/photos/f-oxymoron/5005146417/

×