Save 37% off PRO during our Black Friday Sale! »

When Not to Use YUI

When Not to Use YUI

Video: http://youtu.be/8cTz73zdDuc?hd=1

In this talk from YUIConf 2012, I provide code samples and real-world anecdotes to illustrate how to decide when to use YUI, when to use vanilla JavaScript, when to consider other libraries, and what the tradeoffs are in terms of performance and maintainability. Advice ranges from simple rules of thumb to more nuanced discussion of complex architectural decisions, with examples drawn from my time working on YUI at Yahoo! and using YUI at SmugMug.

683e9380d7cc0724a35dadfb4eeb142b?s=128

Ryan Grove

November 15, 2012
Tweet

Transcript

  1. Howdy! I’m Ryan Grove @yaypie on Twitter and ADN

  2. I work at

  3. I used to work at

  4. I once modeled for a Japanese clothing catalog me

  5. Things I like:

  6. kittens movies with happy endings pie awesomeness JavaScript movies with

    sad endings the ocean not giving talks YUI driving really fast gadgets old-ass sailing ships coffee unit tests sleeping in Pocky thunderstorms
  7. kittens movies with happy endings pie awesomeness JavaScript movies with

    sad endings the ocean not giving talks driving really fast old-ass sailing ships gadgets coffee unit tests sleeping in Pocky thunderstorms YUI
  8. YUI When Not to Use

  9. A library makes hard or annoying tasks easier

  10. Libraries are awesome

  11. But a library shouldn’t try to do everything http://www.flickr.com/photos/justinbaeder/5318402022/

  12. A good library does one thing well http://www.flickr.com/photos/scttw/1335967584/

  13. Despite the name, YUI is a framework

  14. A framework is a collection of like- minded libraries

  15. Library == tool Framework == toolbox http://www.flickr.com/photos/caldwellian/504891328/

  16. Don’t try to use every tool in the toolbox http://www.flickr.com/photos/75905404@N00/7126147125/

  17. Don’t use a tool just because you have a tool

    http://www.flickr.com/photos/carlwain/3555650607/
  18. http://quibly.deviantart.com/art/Admiral-Ackbar-156351053

  19. Understand the tradeoffs

  20. Don’t be lazy http://www.flickr.com/photos/ggunson/21535407/

  21. Be curious http://www.flickr.com/photos/giaky88/4189310121/

  22. Don’t use YUI when vanilla JavaScript will do

  23. Enough philosophy. Let’s get real. The Matrix (1999), Warner Bros.

    Pictures
  24. Don’t use the following Y.Lang methods AVOID

  25. Y.Lang.isBoolean() Chrome 22 IE 9 Firefox 16 iOS 6 1%

    slower 45% slower 9% slower 5% slower Compared to typeof value === ‘boolean’ http://jsperf.com/y-lang-isboolean AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  26. Y.Lang.isFunction() Chrome 22 IE 9 Firefox 16 iOS 6 58%

    slower 68% slower 64% slower 75% slower Compared to typeof value === ‘function’ http://jsperf.com/y-lang-isfunction AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  27. Y.Lang.isNull() Chrome 22 IE 9 Firefox 16 iOS 6 3%

    slower 48% slower 10% slower 3% slower Compared to value === null http://jsperf.com/y-lang-isnull AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  28. Y.Lang.isString() Chrome 22 IE 9 Firefox 16 iOS 6 1%

    slower 49% slower 8% slower 6% slower Compared to typeof value === ‘string’ http://jsperf.com/y-lang-isstring AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  29. Chrome 22 IE 9 Firefox 16 iOS 6 0.4% slower

    47% slower 7% slower 5% slower Y.Lang.isUndefined() Compared to typeof value === ‘undefined’ http://jsperf.com/y-lang-isundefined AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  30. Chrome 22 IE 9 Firefox 16 iOS 6 isBoolean() isFunction()

    isNull() isString() isUndefined() 1% slower 45% slower 9% slower 5% slower 58% slower 68% slower 64% slower 75% slower 3% slower 48% slower 10% slower 3% slower 1% slower 49% slower 8% slower 6% slower 0.4% slower 47% slower 7% slower 5% slower
  31. Consider not using these Y.Lang methods: isNumber() isObject() caution

  32. These ones are cool: isArray() isDate() isValue() now() type() Okay!

  33. Y.instanceOf() Chrome 22 IE 9 Firefox 16 iOS 6 26%

    slower 58% slower 53% slower 49% slower Compared to the instanceof operator http://jsperf.com/y-instanceof AVOID Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  34. Let’s go after the big fish Jaws (1975), Universal Studios

  35. Y.Base caution

  36. Y.Base caution •Initializer/destructor lifecycle •Y.Attribute •Y.EventTarget •Attribute aggregation

  37. Y.Base.create() caution Y.Base.create('myClass', Y.Base, [...], { ... }, { ...

    });
  38. TANSTAAFL

  39. Chrome 22 IE 9 Firefox 16 iOS 6 99.7% slower

    99.6% slower 99.9% slower 99.8% slower Y.Base vs. vanilla JS Comparing instantiation speed http://jsperf.com/y-base caution Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0
  40. Y.Base vs. vanilla JS Comparing instantiation speed (ops/sec) http://jsperf.com/y-base caution

    Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0 Chrome 22 IE 9 Firefox 16 iOS 6 Y.Base vanilla JS 10,924 2,323 6,196 1,717 4,013,182 544,036 8,189,437 713,684
  41. caution •~2,040 bytes per Y.Base instance •1,000 Y.Base instances: ~1.9MB

    •~12 bytes per vanilla JS instance •1,000 vanilla instances: ~11.7KB Y.Base memory usage
  42. You may be using Y.Base without realizing it

  43. Y.Anim Y.App Y.AutoComplete Y.Button Y.Cache Y.Calendar Y.DataSource.* Y.DataTable Y.DD.* Y.Dial

    Y.EditorBase Y.LazyModelList Y.Model Y.ModelList Y.Overlay Y.Panel Y.Pjax Y.Record Y.Recordset Y.Resize Y.Router Y.ScrollView Y.Slider Y.Sortable Y.Tab Y.TabView Y.ToggleButton Y.Uploader Y.View Y.Widget Y.WidgetParent Y.WidgetChild
  44. •When you need attributes •...and events •...and an initializer/destructor lifecycle

    •...and extensions When is Y.Base worth using?
  45. Use only what you need

  46. Consider how many instances you’ll be creating

  47. Be careful with Y.Model and Y.View caution

  48. Sorry. :(

  49. Case study: SmugMug Search

  50. None
  51. Not so fast...

  52. My God, it’s full of models and views 2001: A

    Space Odyssey (1968), MGM Studios
  53. Model + View Model + View Model + View Model

    + View Model + View Model + View Model + View Model + View Model + View Model + View Model + View Model + View
  54. http://www.flickr.com/photos/koskisuomi/1453645876/ Don’t forget about users with old, slow machines

  55. Memory leaks suck http://www.flickr.com/photos/vrogy/511644410/

  56. One view to rule them all

  57. •Throttled scroll event handlers •Efficiently-computed scroll metrics •Convenient events for

    actions like scrollToBottom and scrollToTop Y.Plugin.ScrollInfo http://yuilibrary.com/yui/docs/api/classes/Plugin.ScrollInfo.html
  58. Remodeling Model

  59. • Same API as ModelList • Contains vanilla JavaScript objects

    instead of Model instances • revive() and free() Model instances as needed Y.LazyModelList http://yuilibrary.com/yui/docs/model-list/#lazymodellist
  60. SmugMug Search benchmarks Before After Time to initial results Initial

    memory usage Time to manually scroll to 1,000 results Memory usage after 1,000 results 1,410ms 950ms (33% faster) 8.26MB 7.23MB (12% less) 30s 22s (27% faster) 42.82MB 15.64MB (63% less)
  61. This got me thinking...

  62. •Y.Lang.sub() doesn’t do enough •Y.Handlebars is often overkill •Underscore templates

    were just right Templating
  63. Y.Handlebars Underscore Y.Template.Micro Render Compile & Render 146,446 ops/s 197,123

    ops/s 205,716 ops/s 4,501 ops/s 28,966 ops/s 36,737 ops/s Y.Template.Micro vs. others http://jsperf.com/y-template-vs-others/6 Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2
  64. Y.TreeView A victim of the YUI Way

  65. Y.Tree Extends Y.Base

  66. Y.Tree Extends Y.Base Y.Tree.Node Vanilla JS constructor

  67. Y.Tree Extends Y.Base Y.Tree.Node Vanilla JS constructor Y.TreeView Extends Y.View

  68. None
  69. Y.Menu Building on lessons learned

  70. None
  71. Brainstorm! Brainstorm (1983), MGM Studios

  72. •Native ECMAScript 5 feature •Supported by all modern browsers •Getters/setters

    •Read-only properties •Super cheap vs. Y.Attribute Object.defineProperty()
  73. Y.Property vs. Y.Attribute Comparing instantiation speed (ops/sec) of base classes

    http://jsperf.com/y-property-vs-y-attribute/4 Benchmarked on a Mac Pro, 2.8GHz quad-core Xeon, 16 GB RAM, OS X 10.8.2 and an iPhone 4S, iOS 6.0 Chrome 22 IE 9 Firefox 16 iOS 6 Y.Attribute Y.Property 22,919 7,140 15,669 4,794 56,222 145% faster 48,276 576% faster 110,163 603% faster 28,508 495% faster
  74. Coming soon to a YUI near you? Maybe. Until then:

    https://github.com/smugmug/yui3
  75. Breaking out of YUI The Shawshank Redemption (1994), Castle Rock

    Entertainment
  76. YUI isn’t a religion

  77. Micro-(libraries|frameworks) to the rescue

  78. But what about dependency management?

  79. Just use YUI Loader

  80. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  81. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  82. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  83. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  84. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  85. YUI({ groups: { 'cdnjs': { base: '//cdnjs.cloudflare.com/ajax/libs', modules: { xregexp:

    { path: '/xregexp/2.0.0/xregexp-min.js' } } } }, onProgress: function (e) { if (e.data[0].name === 'xregexp') { YUI.add('xregexp', function (Y) { Y.XRegExp = XRegExp; }); } } }).use('xregexp', function (Y) { console.log('xregexp is now available at Y.XRegExp'); });
  86. YUI wants you to succeed

  87. Be curious

  88. Be pragmatic

  89. Read the source

  90. Be loyal to your users, not your tools

  91. Thank you! @yaypie on Twitter and ADN rgrove on GitHub

    & Freenode https://speakerdeck.com/yaypie/when-not-to-use-yui