KEMBAR78
JavaScript Performance (at SFJS) | PPTX
JavaScript
Performance



                        stevesouders.com/docs/sfjs-20120112.pptx
      Disclaimer: This content does not necessarily reflect the opinions of my employer.
YSlow   Cuzillion SpriteMe Hammerhead
Web
WPO       Performance
          Optimization
drives traffic
improves UX
increases revenue
reduces costs
What’s the #1
cause of slow
web pages?
JAVASCRIPT!
all requests containing “.js” are skipped
http://httparchive.org/trends.php?s=intersection
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
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
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
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
20??: markup
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
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
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/
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);
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
localStorage
yuiblog.com/blog/2007/01/04/performance-research-part-2/
blaze.io/mobile/understanding-mobile-cache-sizes/
Home screen apps on iPhone are slower
because resources are re-requested
even though they should be read from
cache.
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
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/
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
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/
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/
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
stevesouders.com/tests/jsorder.php
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
async=true fixes this (except Opera)

stevesouders.com/tests/jsorder.php
<html>
  <head>
            A
     <link rel=stylesheet ...>
     <style>...</style>
     <script [...]></script>
            B
  </head>
  <body>
     <div>
     <p>
     <ul>
             C
  </body>
</html>

onload:      D
A




    script loads sooner
    beacon fires sooner
    blocks other async (Opera)
    may block rendering
B

    script loads later
    beacon fires later
    blocks fewer async (Opera)
    may block rendering
script loads last
    beacon fires late
    doesn’t block async
C   doesn’t block rendering
script loads after page
    beacon fires very late
    doesn’t block async
    doesn’t block rendering
    onload fires sooner
D
more
stevesouders.com/blog/2011/12/01/silk-ipad-galaxy-comparison/
stevesouders.com/mobileperf/mobileperfbkm.php
Top 100




Top 1000
takeaways
WPO                GA snippet is good
WebPagetest.org    Loadtimer.org
Cuzillion.com      MobilePerf.org
Browserscope.org   HTTPArchive.org
ControlJS.org      Velocity
localStorage       stevesouders.com
@souders
http://stevesouders.com/docs/sfjs-20120112.pptx

JavaScript Performance (at SFJS)

  • 1.
    JavaScript Performance stevesouders.com/docs/sfjs-20120112.pptx Disclaimer: This content does not necessarily reflect the opinions of my employer.
  • 2.
    YSlow Cuzillion SpriteMe Hammerhead
  • 3.
    Web WPO Performance Optimization drives traffic improves UX increases revenue reduces costs
  • 4.
    What’s the #1 causeof slow web pages?
  • 5.
  • 8.
    all requests containing“.js” are skipped
  • 9.
  • 10.
    1995: scripts inHEAD <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 scriptsto 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 scriptsasync 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
  • 14.
  • 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 aJavaScript 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 aJavaScript 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
  • 20.
  • 21.
  • 22.
  • 23.
    Home screen appson 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 1stdoc: 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 AsyncSnippet 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
  • 30.
  • 32.
    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 async=true fixes this (except Opera) stevesouders.com/tests/jsorder.php
  • 33.
    <html> <head> A <link rel=stylesheet ...> <style>...</style> <script [...]></script> B </head> <body> <div> <p> <ul> C </body> </html> onload: D
  • 34.
    A script loads sooner beacon fires sooner blocks other async (Opera) may block rendering
  • 35.
    B script loads later beacon fires later blocks fewer async (Opera) may block rendering
  • 36.
    script loads last beacon fires late doesn’t block async C doesn’t block rendering
  • 37.
    script loads afterpage beacon fires very late doesn’t block async doesn’t block rendering onload fires sooner D
  • 38.
  • 40.
  • 41.
  • 46.
  • 48.
    takeaways WPO GA snippet is good WebPagetest.org Loadtimer.org Cuzillion.com MobilePerf.org Browserscope.org HTTPArchive.org ControlJS.org Velocity localStorage stevesouders.com
  • 49.

Editor's Notes

  • #2 Permission to use photo given by Amnemona: http://www.flickr.com/photos/marinacvinhal/379111290/
  • #3 flickr.com/photos/bekahstargazing/318930460/
  • #4 flickr.com/photos/pedromourapinheiro/3123885534/
  • #5 http://www.flickr.com/photos/peterblapps/838125790/
  • #6 http://www.flickr.com/photos/salty_soul/5799650534/
  • #8 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
  • #9 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
  • #16 flickr.com/photos/gevertulley/4771808965/Generallyasync &amp; 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
  • #20 GMail Mobile: http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.htmlSproutCore: http://blog.sproutcore.com/post/225219087/faster-loading-through-eval
  • #21 flickr.com/photos/bryanpearson/564703455/
  • #25 flickr.com/photos/bryanpearson/564703455/
  • #26 flickr.com/photos/nelsoncruz/431244400/
  • #35 block other async scripts in Operaexecute ASAPsend beacon before leaving pageblock UI thread
  • #36 block other async scripts in Operaexecute ASAPsend beacon before leaving pageblock UI thread
  • #37 block other async scripts in Operaexecute ASAPsend beacon before leaving pageblock UI thread
  • #38 block other async scripts in Operaexecute ASAPsend beacon before leaving pageblock UI thread
  • #39 flickr.com/photos/dualphoto/2609096047/
  • #49 flickr.com/photos/myklroventine/4062102754/