SlideShare a Scribd company logo
Achieving
Performance Zen
   with YUI 3




     Ryan Grove
      YUI Team
Achieving Performance Zen with YUI 3
“Every 100ms delay costs 1% of sales.”
    – Greg Linden, Amazon.com
The economics of web performance
          are simple.
Users prefer fast websites.
Better user experience means more users.
    More users means more money.
“Premature optimization is the root of all evil.”
            – Lazy programmers
“Must go faster!”
        – “Rock star” programmers



“Premature optimization is the root of all evil.”
            – Lazy programmers
“There is no doubt that the grail of
   efficiency leads to abuse. Programmers
waste enormous amounts of time thinking about, or
worrying about, the speed of noncritical parts of
  their programs, and these attempts at efficiency
 actually have a strong negative impact
when debugging and maintenance are considered.”
                – Donald Knuth
“We should forget about small efficiencies, say
 about 97% of the time: premature optimization is
               the root of all evil.”
           – Donald Knuth (cont’d)
“Yet we should not pass up our opportunities in
that critical 3%. A good programmer will not be
 lulled into complacency by such reasoning, he will
   be wise to look carefully at the critical
code; but only after that code has been identified.”
               – Donald Knuth (cont’d)
      http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf
Achieving Performance Zen with YUI 3
Too slow
Too slow   Not worth it
Too slow   Just right!   Not worth it
Just right!
YUI 3 uses careful abstractions to provide the
  best possible balance between user
     efficiency and developer efficiency.
Sweet spot




             Effort vs. gains




Low / High                      High / Low
In a single, highly modular library, we provide
support for all capable browsers, including
                 mobile browsers.
Capability based loading allows us to
 deliver streamlined code to all browsers.
Mobile Safari shouldn’t have to suffer for
            IE6’s sins.
As with any abstraction layer, it’s important to
 understand what’s being abstracted.
Certain tradeoffs are made in order to increase
           developer efficiency.
If you find that this impacts user efficiency,
           you can shift the balance.
Bootstrapping
Seed bootstrap
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-min.js"></
script>

<script>
YUI().use('node', function (Y) {

});
</script>
239ms
Seed + Loader bootstrap
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/loader/loader-min.js"></script>

<script>
YUI().use('node', function (Y) {

});
</script>
Seed + Loader bootstrap
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/loader/loader-min.js"></script>

<script>
YUI().use('node', function (Y) {

});
</script>
177ms (-62ms)
No bootstrap
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/oop/oop-min.js&3.2.0pr2/build/dom/dom-
min.js&3.2.0pr2/build/event-custom/event-custom-base-min.js&3.2.0pr2/build/
event/event-base-min.js&3.2.0pr2/build/pluginhost/pluginhost-min.js&3.2.0pr2/
build/node/node-min.js&3.2.0pr2/build/event/event-delegate-min.js"></script>

<script>
YUI({bootstrap: false}).use('*', function (Y) {

});
</script>
No bootstrap
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/oop/oop-min.js&3.2.0pr2/build/dom/dom-
min.js&3.2.0pr2/build/event-custom/event-custom-base-min.js&3.2.0pr2/build/
event/event-base-min.js&3.2.0pr2/build/pluginhost/pluginhost-min.js&3.2.0pr2/
build/node/node-min.js&3.2.0pr2/build/event/event-delegate-min.js"></script>

<script>
YUI({bootstrap: false}).use('*', function (Y) {

});
</script>
118ms (-121ms)
Build-time concatenation
#!/usr/bin/env ruby
require 'open-uri'

ROOT = 'http://yui.yahooapis.com/combo?'
PATH = '3.2.0pr2/build/'

MODULES = [
  'yui/yui-min.js',
  'oop/oop-min.js',
  'dom/dom-min.js',
  'event-custom/event-custom-base-min.js',
  'event/event-base-min.js',
  'pluginhost/pluginhost-min.js',
  'node/node-min.js',
  'event/event-delegate-min.js'
]

open(ROOT + PATH + MODULES.join("&#{PATH}")) do |yui|
 puts yui.read
end



$ ./yui-concat.rb > local-yui-min.js
Lazy bootstrap (use responsibly)
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/loader/loader-min.js"></script>

<script>
window.onload = function () {
 YUI().use('node', function (Y) {

 });
};
</script>
Lazy bootstrap (use responsibly)
<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui-
min.js&3.2.0pr2/build/loader/loader-min.js"></script>

<script>
window.onload = function () {
 YUI().use('node', function (Y) {

 });
};
</script>
72ms (-167ms)
Native vs. non-native
YUI uses native APIs when they’re available
    and emulates them when they aren’t.
Selectors
Y.one('.foo');
Selectors
Y.one('.foo');




       Y.Node
Selectors
Y.one('.foo');




       Y.Node     Y.Selector
Selectors
Y.one('.foo');




       Y.Node     Y.Selector




                   Native?
Selectors
Y.one('.foo');




       Y.Node            Y.Selector




     emulated
                          Native?
   querySelector
                   No
Selectors
Y.one('.foo');




       Y.Node            Y.Selector




                                            About 1.5x as fast

     emulated                                    native
                          Native?
   querySelector                              querySelector
                   No                 Yes
JSON
Y.JSON.parse(jsonString);
Y.JSON.stringify(someObject);
JSON
Y.JSON.parse(jsonString);
Y.JSON.stringify(someObject);




                                Y.JSON
JSON
Y.JSON.parse(jsonString);
Y.JSON.stringify(someObject);




                                Y.JSON




                                Native?
JSON
Y.JSON.parse(jsonString);
Y.JSON.stringify(someObject);




                                Y.JSON




     emulated
                                Native?
      JSON
                         No
JSON
Y.JSON.parse(jsonString);
Y.JSON.stringify(someObject);




                                Y.JSON



                                            Parse: about 22x as fast
                                           Stringify: about 19x as fast

     emulated
                                Native?            native JSON
      JSON
                         No               Yes
Transitions
YUI().use('transition', function (Y) {
  Y.one('#demo').transition({
      duration: 1,
      easing: 'ease-out',
      height: '10px',
      width: '10px',

          // Per-property duration and easing.
          opacity: {
             value: 0,
             duration: 2,
             easing: 'ease-in'
          }
      }, function () {
          Y.log('transition finished!');
      });
});
opacity: {
             value: 0,
             duration: 2,
             easing: 'ease-in'
          }
      }, function () {
          Y.log('transition finished!');
      });
});




                                          Y.Transition
opacity: {
             value: 0,
             duration: 2,
             easing: 'ease-in'
          }
      }, function () {
          Y.log('transition finished!');
      });
});




                                          Y.Transition




                                            Native?
opacity: {
             value: 0,
             duration: 2,
             easing: 'ease-in'
          }
      }, function () {
          Y.log('transition finished!');
      });
});




                                          Y.Transition




         emulated
                                            Native?
        transitions
                                No
opacity: {
             value: 0,
             duration: 2,
             easing: 'ease-in'
          }
      }, function () {
          Y.log('transition finished!');
      });
});




                                          Y.Transition




                                                               About 32% less CPU

         emulated                                                    native
                                            Native?
        transitions                                                transitions
                                No                       Yes
Performance helpers
Y.cached()
    Provides simple function memoization.
  Included in the YUI seed, so it’s always available.
var factorial = Y.cached(function (n) {
    return (n === 0 || n === 1) ? 1 : n * factorial(n - 1);
});
Y.cached()
    Provides simple function memoization.
  Included in the YUI seed, so it’s always available.
var factorial = Y.cached(function (n) {
    return (n === 0 || n === 1) ? 1 : n * factorial(n - 1);
});


factorial(150);   //   150 function calls
factorial(150);   //   1 function call
factorial(100);   //   1 function call
factorial(160);   //   11 function calls
Cache Utility
          Provides a fixed-size memory cache for
                        key/value pairs.
YUI().use('cache', function (Y) {
  var cache = new Y.Cache({max: 10});

      function expensive(n) {
        var cachedResult = cache.retrieve('result' + n),
           result;

          if (cachedResult) {
              return cachedResult.response;
          }

          result = 0;

          while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});
YUI().use('cache', function (Y) {
  var cache = new Y.Cache({max: 10});

      function expensive(n) {
        var cachedResult = cache.retrieve('result' + n),
           result;

          if (cachedResult) {
              return cachedResult.response;
          }

          result = 0;

          while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});



expensive(10000000); // about 360ms
expensive(10000000); // <1ms
CacheOffline Utility

               Extends Cache to use localStorage.

YUI().use('cache', function (Y) {
  var cache = new Y.CacheOffline({expires: 1800000}); // 30 minutes

      function expensive(n) {
        var cachedResult = cache.retrieve('result' + n),
           result;

          if (cachedResult) {
              return cachedResult.response;
          }

          result = 0;

          while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});
CacheOffline Utility

               Extends Cache to use localStorage.

YUI().use('cache', function (Y) {
  var cache = new Y.CacheOffline({expires: 1800000}); // 30 minutes

      function expensive(n) {
        var cachedResult = cache.retrieve('result' + n),
           result;

          if (cachedResult) {
              return cachedResult.response;
          }

          result = 0;

          while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});
YUI().use('cache', function (Y) {
  var cache = new Y.CacheOffline({expires: 1800000}); // 30 minutes

      function expensive(n) {
        var cachedResult = cache.retrieve('result' + n),
           result;

          if (cachedResult) {
              return cachedResult.response;
          }

          result = 0;

          while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});



expensive(10000000); // about 360ms
expensive(10000000); // 1ms
while (result < n) {
            result += 1;
          }

          cache.add('result' + n, result);
          return result;
      }
});



expensive(10000000); // about 360ms
expensive(10000000); // 1ms




                                   New pageview



expensive(10000000); // 1ms
expensive(10000000); // 1ms
ImageLoader
<img id="img1">
<img id="img2">
<div style="height: 1000px"></div>
<img id="img3">

<script src="http://yui.yahooapis.com/combo?3.2.0pr2/build/yui/yui.js"></
script>

<script>
YUI().use('imageloader', function (Y) {
 var foldGroup = new Y.ImgLoadGroup({foldDistance: 25});

  foldGroup.registerImage({domId: 'img1', srcUrl: 'aardvark.jpg'});
  foldGroup.registerImage({domId: 'img2', srcUrl: 'bumblebee.jpg'});
  foldGroup.registerImage({domId: 'img3', srcUrl: 'cheetah.jpg'});
});
</script>
Achieving Performance Zen with YUI 3
Achieving Performance Zen with YUI 3
AsyncQueue
YUI().use('async-queue', function (Y) {
 var q = new Y.AsyncQueue(function () {
   // do something expensive
 }, function () {
   // do another expensive thing
 }, function () {
   // and another!
 });

  q.run();
});
AsyncQueue
YUI().use('async-queue', function (Y) {
 var q = new Y.AsyncQueue(function () {
   // do something expensive
 }, function () {
   // do another expensive thing
 }, function () {
   // and another!
 });

  q.run();
});




     Task 1           UI
AsyncQueue
YUI().use('async-queue', function (Y) {
 var q = new Y.AsyncQueue(function () {
   // do something expensive
 }, function () {
   // do another expensive thing
 }, function () {
   // and another!
 });

  q.run();
});




     Task 1           UI            Task 2   UI
AsyncQueue
YUI().use('async-queue', function (Y) {
 var q = new Y.AsyncQueue(function () {
   // do something expensive
 }, function () {
   // do another expensive thing
 }, function () {
   // and another!
 });

  q.run();
});




     Task 1           UI            Task 2   UI   Task 3
Design code with performance in mind.
Always optimize when it’s easy.
Tackle harder optimizations if it will
measurably improve the user experience.
Profiling tools
YUI Profiler
YUI().use('profiler', function (Y) {
 Y.Profiler.registerObject('Assist', Y.Search.Assist.Util);

 // ... after a bit of usage ...

  console.log(Y.Profiler.getFullReport());
});
WebKit Profiler
WebKit Timeline Panel
Firebug Profiler
dynaTrace
jsPerf.com
Achieving Performance Zen with YUI 3
User efficiency is most important.
User efficiency is most important.
Developer efficiency is important, but less
        so than user efficiency.
User efficiency is most important.
Developer efficiency is important, but less
        so than user efficiency.
Efficiency for its own sake is least important.
Find your own zen.
Photo & illustration credits

•   http://www.flickr.com/photos/josefeliciano/3849557951/
•   http://www.flickr.com/photos/mgspiller/203376307/
•   http://www.flickr.com/photos/formulaphoto/2625359503/
•   http://www.flickr.com/photos/paulwoolrich/135550296/
•   http://en.wikipedia.org/wiki/File:Dore-munchausen-illustration.jpg
•   Laden Swallow by YUI’s own Allen Rabinovich
•   http://www.flickr.com/photos/poetatum/3457696479/
•   http://www.flickr.com/photos/dipthongasaurus_rex/3530738527/
•   http://www.flickr.com/photos/vickisnature/2923728081/
•   http://www.flickr.com/photos/80835774@N00/2380266276/
•   http://www.flickr.com/photos/wwarby/4915969081/
•   http://www.flickr.com/photos/euart/282104427/

More Related Content

PDF
Let'swift "Concurrency in swift"
PDF
Actor Concurrency
PDF
Java Concurrency Gotchas
PDF
Java Concurrency Idioms
PDF
Java Concurrency Gotchas
PPTX
Making Java more dynamic: runtime code generation for the JVM
PPTX
Effective java - concurrency
PPT
Clojure concurrency
Let'swift "Concurrency in swift"
Actor Concurrency
Java Concurrency Gotchas
Java Concurrency Idioms
Java Concurrency Gotchas
Making Java more dynamic: runtime code generation for the JVM
Effective java - concurrency
Clojure concurrency

What's hot (20)

DOCX
Java 5 concurrency
PDF
Bytecode manipulation with Javassist and ASM
PPTX
Common mistakes in android development
PDF
Koin Quickstart
PPTX
Kotlin Language Features - A Java comparison
PPTX
Javascript basics for automation testing
ODP
Java memory model
PDF
Async js - Nemetschek Presentaion @ HackBulgaria
PDF
A Brief Introduction to the Qt Application Framework
PDF
Kotlin, smarter development for the jvm
PPT
Advanced Javascript
PDF
Lsl scripts
PDF
Develop your next app with kotlin @ AndroidMakersFr 2017
PPT
PDF
Kotlin in action
PPTX
Byte code field report
PDF
Kotlin advanced - language reference for android developers
PPTX
Advanced JavaScript
PDF
Kotlin for Android - Vali Iorgu - mRready
PPT
Java if and else
Java 5 concurrency
Bytecode manipulation with Javassist and ASM
Common mistakes in android development
Koin Quickstart
Kotlin Language Features - A Java comparison
Javascript basics for automation testing
Java memory model
Async js - Nemetschek Presentaion @ HackBulgaria
A Brief Introduction to the Qt Application Framework
Kotlin, smarter development for the jvm
Advanced Javascript
Lsl scripts
Develop your next app with kotlin @ AndroidMakersFr 2017
Kotlin in action
Byte code field report
Kotlin advanced - language reference for android developers
Advanced JavaScript
Kotlin for Android - Vali Iorgu - mRready
Java if and else
Ad

Viewers also liked (6)

PPS
Hamdan international photography award
PPS
用50元買來的CEO
KEY
YUI Gallery
PPS
如果少了那個人
PPS
逆向思考
KEY
YUI 3: The Most Advance JavaScript Library in the World
Hamdan international photography award
用50元買來的CEO
YUI Gallery
如果少了那個人
逆向思考
YUI 3: The Most Advance JavaScript Library in the World
Ad

Similar to Achieving Performance Zen with YUI 3 (20)

PPTX
The next step, part 2
PDF
Async JavaScript Unit Testing
PPTX
Introduction to Node.js
PPTX
Security testing of YUI powered applications
PDF
Douglas Crockford: Serversideness
PDF
Server Side JavaScript - You ain't seen nothing yet
PPTX
Get started with YUI
PDF
Think Async: Asynchronous Patterns in NodeJS
PDF
Basics of JavaScript
PDF
The evolution of java script asynchronous calls
PDF
The Evolution of Async-Programming (SD 2.0, JavaScript)
PPT
Java basic tutorial by sanjeevini india
PPT
Java basic tutorial by sanjeevini india
KEY
Playing With Fire - An Introduction to Node.js
PPTX
jQuery
KEY
Lock? We don't need no stinkin' locks!
KEY
Locks? We Don't Need No Stinkin' Locks - Michael Barker
KEY
Java&Script
PDF
Functional Reactive Programming / Compositional Event Systems
The next step, part 2
Async JavaScript Unit Testing
Introduction to Node.js
Security testing of YUI powered applications
Douglas Crockford: Serversideness
Server Side JavaScript - You ain't seen nothing yet
Get started with YUI
Think Async: Asynchronous Patterns in NodeJS
Basics of JavaScript
The evolution of java script asynchronous calls
The Evolution of Async-Programming (SD 2.0, JavaScript)
Java basic tutorial by sanjeevini india
Java basic tutorial by sanjeevini india
Playing With Fire - An Introduction to Node.js
jQuery
Lock? We don't need no stinkin' locks!
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Java&Script
Functional Reactive Programming / Compositional Event Systems

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Machine Learning_overview_presentation.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
Big Data Technologies - Introduction.pptx
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
1. Introduction to Computer Programming.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Tartificialntelligence_presentation.pptx
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Spectral efficient network and resource selection model in 5G networks
Dropbox Q2 2025 Financial Results & Investor Presentation
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
The Rise and Fall of 3GPP – Time for a Sabbatical?
A comparative analysis of optical character recognition models for extracting...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Per capita expenditure prediction using model stacking based on satellite ima...
Machine Learning_overview_presentation.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Big Data Technologies - Introduction.pptx
NewMind AI Weekly Chronicles - August'25-Week II
Unlocking AI with Model Context Protocol (MCP)
1. Introduction to Computer Programming.pptx
Network Security Unit 5.pdf for BCA BBA.
20250228 LYD VKU AI Blended-Learning.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Tartificialntelligence_presentation.pptx
Encapsulation_ Review paper, used for researhc scholars
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf

Achieving Performance Zen with YUI 3

Editor's Notes

  • #4: From http://sites.google.com/site/glinden/Home/StanfordDataMining.2006-11-28.ppt
  • #9: Knuth wrote this in &amp;#x201C;Structured Programming with Goto Statements&amp;#x201D;, an article published in Computing Surveys, Vol. 6, No. 4, in December 1974: http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf
  • #10: Knuth later attributed this to Sir Tony Hoare, who claims not to have said it.
  • #24: Time to window.onload.
  • #27: Time to window.onload.
  • #30: Time to window.onload.
  • #32: Dynamically-added script nodes block window.onload in FF, Chrome, and Safari, but not in IE and Opera (so this technique might not be as useful there). HTML5 specifies that script nodes should block onload.
  • #34: Time to window.onload. Caveat: overall time to interactivity is 122ms. May improve perceived performance at the expense of actual performance.
  • #37: Performance comparison: http://jsperf.com/yui-3-selector-vs-native-queryselector/ (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #38: Performance comparison: http://jsperf.com/yui-3-selector-vs-native-queryselector/ (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #39: Performance comparison: http://jsperf.com/yui-3-selector-vs-native-queryselector/ (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #40: Performance comparison: http://jsperf.com/yui-3-selector-vs-native-queryselector/ (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #41: Performance comparison: http://jsperf.com/yui-3-selector-vs-native-queryselector/ (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #42: Performance comparison: http://jsperf.com/yui-3-json-vs-native (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #43: Performance comparison: http://jsperf.com/yui-3-json-vs-native (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #44: Performance comparison: http://jsperf.com/yui-3-json-vs-native (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #45: Performance comparison: http://jsperf.com/yui-3-json-vs-native (quoted results are from Firefox 4.0b3 on Mac OS 10.6.4).
  • #47: Tested in Safari 5.0.1 on Mac OS 10.6.4 with native transitions enabled vs. disabled, using Instruments to track CPU utilization.
  • #48: Tested in Safari 5.0.1 on Mac OS 10.6.4 with native transitions enabled vs. disabled, using Instruments to track CPU utilization.
  • #49: Tested in Safari 5.0.1 on Mac OS 10.6.4 with native transitions enabled vs. disabled, using Instruments to track CPU utilization.
  • #76: YUI can help, but ultimately, only you can find your own performance zen. There&amp;#x2019;s no one-size-fits-all solution.
  • #77: All photos used under Creative Commons licenses. Munchausen illustration under public domain. Awesome &amp;#x201C;Laden Swallow&amp;#x201D; illustration used by permission of the artist.