All You Can Leet A heaping helping of  performance , selector  engines,  &   sandbox  natives By  John-David Dalton  @jdal...
function times(iterator, context) { $R( 0, this, true ) . each( iterator, context ) ; return this; } Performance Reduce Ab...
Performance function times(iterator, context) { var i = -1, length = this; while ( ++i < length )  iterator.call(context, ...
Performance function contains(element, descendant) { if (element. compareDocumentPosition ) { return (descendant .compareD...
function isHostObject(object, property) { var type = typeof object[property]; return type === ' object ' ? !!object[proper...
var type = typeof object[property]; return type === ' object ' ? !!object[property] : !/^( boolean | number | string | und...
var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) ...
<ul><li>But don't fork Marsellus Wallace ! </li></ul>var contains = function(element, descendant) { while ( descendant = d...
<ul><li>Memoize </li></ul>var  cache = { } , reHyphenated = /-([a-z])/gi, uid = +new Date; function toUpperCase(match, let...
<ul><li>Choose Your Engine </li></ul><ul><ul><li>base2 </li></ul></ul><ul><ul><li>DomAssistant </li></ul></ul><ul><ul><li>...
<ul><ul><li>base2 </li></ul></ul><ul><ul><li>DomAssistant </li></ul></ul><ul><ul><li>IDQuery </li></ul></ul><ul><ul><li>Ll...
NWMatcher Chrome 1+ Firefox 1.5+ IE 6+ Opera 9.0+ Safari 2.0+   Legacy Chrome 1+ Firefox 1.5+ IE 6+ Opera 9.25+ Safari 2.0...
E E#fooId E.fooClass E F E > F E + F F ~ F F[foo] F[foo=&quot;bar&quot;] E[foo^=&quot;bar&quot;] E[foo$=&quot;bar&quot;] E...
<ul><li>QuerySelectorAll Bug Fixes </li></ul>NWMatcher Sizzle Prototype 1.6.1+ <ul><ul><li>Quirks className case-sensitivi...
CSS 3 Selector Tests: Legacy Selector Engines
CSS 3 Selector Tests: Sizzle Selector Engines
CSS 3 Selector Tests: NWMatcher Selector Engines
<ul><li>Match Maker </li></ul><ul><li>[  event delegation; higher score is better  ] </li></ul>Selector Engines
Performance [  higher score is better  ] Selector Engines
Performance [  higher score is better  ] Selector Engines
Make the Switch <ul><ul><li>rake dist SELECTOR_ENGINE = nwmatcher </li></ul></ul>Selector Engines
<ul><li>The Problem </li></ul>Array.prototype.size = function() { return this.length; }; var arr = [1, 2, 3]; arr.size(); ...
<ul><li>The Problem </li></ul>// framework X defines a method Function.prototype.defer = function() { var fn = this,  args...
<ul><li>The Problem </li></ul>// framework X defines a method Array.prototype. reduce = function()  { return this.length >...
<ul><li>The Solution </li></ul>// Sandbox natives to the rescue fuse.Array.prototype.size  = function() { return fuse.Numb...
<ul><li>Browsers Tested </li></ul><ul><ul><ul><li>IE 5.5+ </li></ul></ul></ul><ul><ul><ul><li>Firefox 1.5+ </li></ul></ul>...
<ul><li>Supported Natives </li></ul><ul><ul><li>fuse.Number </li></ul></ul><ul><ul><li>fuse.Object </li></ul></ul><ul><ul>...
<ul><li>Usage </li></ul>var str = fuse.String('bacon'); // sandbox natives cannot be primitives typeof str;  // object // ...
<ul><li>What's Cool </li></ul>// Multiple sandboxed natives fuse.Array; fuse.dom.NodeList = (new fuse.Fusebox).Array; // j...
FuseJS <ul><li>Fuse JavaScript Framework </li></ul>
FuseJS <ul><li>Browsers Tested </li></ul><ul><ul><ul><li>IE 6+ </li></ul></ul></ul><ul><ul><ul><li>Firefox 1.5+ </li></ul>...
FuseJS <ul><ul><ul><li>Sandbox Native [  better 3rd party & browser support  ] </li></ul></ul></ul><ul><ul><ul><li>Perform...
FuseJS <ul><ul><ul><li>Modular </li></ul></ul></ul><ul><ul><ul><li>[  less abstraction, custom builds  ] </li></ul></ul></...
FuseJS <ul><ul><ul><li>Enforce FIFO Event Observer Order </li></ul></ul></ul><ul><ul><ul><li>[  cross-browser and fixes ed...
FuseJS Performance [  lower score is better  ]
FuseJS Performance [  lower score is better  ]
FuseJS Performance [  IE8 - lower score is better  ]
FuseJS Performance [  lower score is better  ]
Links <ul><ul><ul><li>http://github.com/jdalton/fusejs </li></ul></ul></ul><ul><ul><ul><li>http://github.com/jdalton/fuseb...
Upcoming SlideShare
Loading in …5
×

JSConf: All You Can Leet

5,321 views
5,270 views

Published on

My JSConf slides.

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,321
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
31
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

JSConf: All You Can Leet

  1. 1. All You Can Leet A heaping helping of performance , selector engines, & sandbox natives By John-David Dalton @jdalton ▪ john@fusejs.com ▪ http://allyoucanleet.com
  2. 2. function times(iterator, context) { $R( 0, this, true ) . each( iterator, context ) ; return this; } Performance Reduce Abstraction
  3. 3. Performance function times(iterator, context) { var i = -1, length = this; while ( ++i < length ) iterator.call(context, i, i); return length; } Reduce Abstraction
  4. 4. Performance function contains(element, descendant) { if (element. compareDocumentPosition ) { return (descendant .compareDocumentPosition(element) & 8) === 8; } if (element. contains ) { return element !== descendant && element.contains(element); } while ( descendant = descendant.parentNode ) { if (descendant == element) return true; } return false; } Fork like Rabbits
  5. 5. function isHostObject(object, property) { var type = typeof object[property]; return type === ' object ' ? !!object[property] : !/^( boolean | number | string | undefined )$/.test(type); } var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) if (descendant === element) return true; } return false; }; if ( isHostObject(docEl, 'compareDocumentPosition') ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostObject(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); } Performance Fork like Rabbits
  6. 6. var type = typeof object[property]; return type === ' object ' ? !!object[property] : !/^( boolean | number | string | undefined )$/.test(type); } var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) return true; } re tur n false; }; if ( isHostObject(docEl, 'compareDocumentPosition') ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostObject(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Performance Fork like Robots
  7. 7. var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) return true; } return false; }; if ( isHostObject( docEl , 'compareDocumentPosition' ) ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostObject(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Performance Fork like Hobbits
  8. 8. <ul><li>But don't fork Marsellus Wallace ! </li></ul>var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) return true; } return false; }; if ( isHostObject(docEl, 'compareDocumentPosition') ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostObject ( docEl , 'contains' ) ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Performance
  9. 9. <ul><li>Memoize </li></ul>var cache = { } , reHyphenated = /-([a-z])/gi, uid = +new Date; function toUpperCase(match, letter) { return letter.toUpperCase(); } function camelCase(string) { var key = uid + string; return cache[ key ] || (cache[ key ] = string.replace( reHyphenated , toUpperCase )) ; } Performance
  10. 10. <ul><li>Choose Your Engine </li></ul><ul><ul><li>base2 </li></ul></ul><ul><ul><li>DomAssistant </li></ul></ul><ul><ul><li>IDQuery </li></ul></ul><ul><ul><li>LlamaLab </li></ul></ul><ul><ul><li>MyLibrary </li></ul></ul><ul><ul><li>Sly </li></ul></ul><ul><ul><li>uuQuery </li></ul></ul><ul><ul><li>YASS </li></ul></ul><ul><ul><li>YUI </li></ul></ul><ul><ul><li>Acme (Dojo) </li></ul></ul><ul><ul><li>DomQuery (ExtJS) </li></ul></ul><ul><ul><li>NWMatcher (FuseJS, Prototype) </li></ul></ul><ul><ul><li>Sizzle (jQuery, MochiKit, Prototype) </li></ul></ul><ul><ul><li>Slick (MooTools) </li></ul></ul>Selector Engines
  11. 11. <ul><ul><li>base2 </li></ul></ul><ul><ul><li>DomAssistant </li></ul></ul><ul><ul><li>IDQuery </li></ul></ul><ul><ul><li>LlamaLab </li></ul></ul><ul><ul><li>MyLibrary </li></ul></ul><ul><ul><li>Sly </li></ul></ul><ul><ul><li>uuQuery </li></ul></ul><ul><ul><li>YASS </li></ul></ul><ul><ul><li>YUI </li></ul></ul><ul><ul><li>Acme (Dojo) </li></ul></ul><ul><ul><li>DomQuery (ExtJS) </li></ul></ul><ul><ul><li>NWMatcher (FuseJS, Prototype) </li></ul></ul><ul><ul><li>Sizzle (jQuery, MochiKit, Prototype) </li></ul></ul><ul><ul><li>Slick (MooTools) </li></ul></ul>Dare to Compare Selector Engines
  12. 12. NWMatcher Chrome 1+ Firefox 1.5+ IE 6+ Opera 9.0+ Safari 2.0+ Legacy Chrome 1+ Firefox 1.5+ IE 6+ Opera 9.25+ Safari 2.0.4 + Sizzle Chrome 1+ Firefox 2.0+ IE 6+ Opera 9.0+ Safari 3.0+ Prototype 1.6.1+ * 1.6.0.3 supports Safari 2.0+ Compatible Source ▪ Compatible ▪ Possible Compatibility ▪ Failed Compatibility Browser Support Selector Engines
  13. 13. E E#fooId E.fooClass E F E > F E + F F ~ F F[foo] F[foo=&quot;bar&quot;] E[foo^=&quot;bar&quot;] E[foo$=&quot;bar&quot;] E[foo*=&quot;bar&quot;] E[foo~=&quot;bar&quot;] E[foo|=&quot;en&quot;] E:root E:empty E:nth-child(n) E:nth-of-type(n) E:nth-last-child(n) NWMatcher Sizzle Prototype 1.6.1+ E:nth-last-of-type(n) E:first-child E:last-child E:only-child E:first-of-type E:last-of-type E:only-of-type E:not(s) E:active E:focus E:enabled E:disabled E:checked E:link E:visited E:target E:lang(t) E:nth-last-of-type(n) E:first-child E:last-child E:only-child E:first-of-type E:last-of-type E:only-of-type E:not(s) E:active E:focus E:enabled E:disabled E:checked E:link E:visited E:target E:lang(t) E:nth-last-of-type(n) E:first-child E:last-child E:only-child E:first-of-type E:last-of-type E:only-of-type E:not(s) E:active E:focus E:enabled E:disabled E:checked E:link E:visited E:target E:lang(t) Not Supported ▪ Supported ▪ Not Supported + Failed Compatibility E E#fooId E.fooClass E F E > F E + F F ~ F F[foo] F[foo=&quot;bar&quot;] E[foo^=&quot;bar&quot;] E[foo$=&quot;bar&quot;] E[foo*=&quot;bar&quot;] E[foo~=&quot;bar&quot;] E[foo|=&quot;en&quot;] E:root E:empty E:nth-child(n) E:nth-of-type(n) E:nth-last-child(n) E E#fooId E.fooClass E F E > F E + F F ~ F F[foo] F[foo=&quot;bar&quot;] E[foo^=&quot;bar&quot;] E[foo$=&quot;bar&quot;] E[foo*=&quot;bar&quot;] E[foo~=&quot;bar&quot;] E[foo|=&quot;en&quot;] E:root E:empty E:nth-child(n) E:nth-of-type(n) E:nth-last-child(n) Legacy Selector Engines Selector Support
  14. 14. <ul><li>QuerySelectorAll Bug Fixes </li></ul>NWMatcher Sizzle Prototype 1.6.1+ <ul><ul><li>Quirks className case-sensitivity </li></ul></ul><ul><ul><li>Quirks mixed case className </li></ul></ul><ul><ul><li>:disable :enabled on input type=&quot;hidden&quot; </li></ul></ul><ul><ul><li>:link matching non-hyperlinks </li></ul></ul><ul><ul><li>:target support </li></ul></ul><ul><ul><li>Matching ^=&quot;&quot; or $=&quot;&quot; </li></ul></ul><ul><ul><li>Source attribute values </li></ul></ul><ul><li>Quirks uppercase className </li></ul><ul><ul><li>Quirks className case-insensitivity </li></ul></ul>Legacy Selector Engines
  15. 15. CSS 3 Selector Tests: Legacy Selector Engines
  16. 16. CSS 3 Selector Tests: Sizzle Selector Engines
  17. 17. CSS 3 Selector Tests: NWMatcher Selector Engines
  18. 18. <ul><li>Match Maker </li></ul><ul><li>[ event delegation; higher score is better ] </li></ul>Selector Engines
  19. 19. Performance [ higher score is better ] Selector Engines
  20. 20. Performance [ higher score is better ] Selector Engines
  21. 21. Make the Switch <ul><ul><li>rake dist SELECTOR_ENGINE = nwmatcher </li></ul></ul>Selector Engines
  22. 22. <ul><li>The Problem </li></ul>Array.prototype.size = function() { return this.length; }; var arr = [1, 2, 3]; arr.size(); // 3 // Excluding the use of newer ES5 methods like // Object.defineProperty() when defining new properties // the inernal [[DefineOwnProperty]] method is called with // a property descriptor containing [[Enumerable]] true. for ( var i in arr ) { // i is 0, 1, 2, `size` } Sandbox Natives
  23. 23. <ul><li>The Problem </li></ul>// framework X defines a method Function.prototype.defer = function() { var fn = this, args = arguments ; return window.setTimeout(function() { fn.apply(fn, args); }, 10); }; // framework Y paves previous method with their own Function.prototype.defer = function( millis, thisArg, args ) { var fn = this; return window.setTimeout(function() { fn.apply(thisArg, args); }, millis); }; Sandbox Natives
  24. 24. <ul><li>The Problem </li></ul>// framework X defines a method Array.prototype. reduce = function() { return this.length > 1 ? this : this[0]; }; // Later, a different implementation is added to ECMAScript // 15.4.4.21 Array#reduce ( callbackfn [ , initialValue ] ) // returns [1, 2, 3] instead of 6 [1, 2, 3].reduce(function(prevValue, value) { return prevValue + value; }); Sandbox Natives
  25. 25. <ul><li>The Solution </li></ul>// Sandbox natives to the rescue fuse.Array.prototype.size = function() { return fuse.Number(this.length); }; var arr = fuse.Array(1, 2, 3); arr.size(); // 3 // won't extend the global Array constructor typeof window.Array.prototype.size ; // undefined Sandbox Natives
  26. 26. <ul><li>Browsers Tested </li></ul><ul><ul><ul><li>IE 5.5+ </li></ul></ul></ul><ul><ul><ul><li>Firefox 1.5+ </li></ul></ul></ul><ul><ul><ul><li>Chrome 1+ </li></ul></ul></ul><ul><ul><ul><li>Konqueror 4.2.2+ </li></ul></ul></ul><ul><ul><ul><li>Opera 9.0+ </li></ul></ul></ul><ul><ul><ul><li>Safari 2.0+ </li></ul></ul></ul>Various JavaScript Engines <ul><ul><li>SpiderMonkey </li></ul></ul><ul><ul><li>SquirrelFish (& Extreme) </li></ul></ul><ul><ul><li>Tamarin </li></ul></ul><ul><ul><li>TraceMonkey </li></ul></ul><ul><ul><li>V8 </li></ul></ul><ul><ul><li>Carakan </li></ul></ul><ul><ul><li>JaegerMonkey </li></ul></ul><ul><ul><li>JavaScriptCore </li></ul></ul><ul><ul><li>KJS </li></ul></ul><ul><ul><li>Nitro </li></ul></ul><ul><ul><li>Rhino </li></ul></ul>Sandbox Natives
  27. 27. <ul><li>Supported Natives </li></ul><ul><ul><li>fuse.Number </li></ul></ul><ul><ul><li>fuse.Object </li></ul></ul><ul><ul><li>fuse.RegExp </li></ul></ul><ul><ul><li>fuse.String </li></ul></ul><ul><ul><li>fuse.Array </li></ul></ul><ul><ul><li>fuse.Boolean </li></ul></ul><ul><ul><li>fuse.Date </li></ul></ul><ul><ul><li>fuse.Function </li></ul></ul>Sandbox Natives
  28. 28. <ul><li>Usage </li></ul>var str = fuse.String('bacon'); // sandbox natives cannot be primitives typeof str; // object // kinda like calling the global String constructor typeof new String('bacon'); // object // internal [[Class]] is still [object String] ({ }).toString.call(str); // chaining works too str.split('').join('').capitalize(); // Bacon Sandbox Natives
  29. 29. <ul><li>What's Cool </li></ul>// Multiple sandboxed natives fuse.Array; fuse.dom.NodeList = (new fuse.Fusebox).Array; // jQuery syntax with real arrays fuse.query('.tabs').addClassName('.active').show(); Sandbox Natives
  30. 30. FuseJS <ul><li>Fuse JavaScript Framework </li></ul>
  31. 31. FuseJS <ul><li>Browsers Tested </li></ul><ul><ul><ul><li>IE 6+ </li></ul></ul></ul><ul><ul><ul><li>Firefox 1.5+ </li></ul></ul></ul><ul><ul><ul><li>Chrome 1+ </li></ul></ul></ul><ul><ul><ul><li>Konqueror 4.2.2 </li></ul></ul></ul><ul><ul><ul><li>Opera 9.0+ </li></ul></ul></ul><ul><ul><ul><li>Safari 2.0+ </li></ul></ul></ul>
  32. 32. FuseJS <ul><ul><ul><li>Sandbox Native [ better 3rd party & browser support ] </li></ul></ul></ul><ul><ul><ul><li>Performance </li></ul></ul></ul><ul><ul><ul><li>[ Reduced abstraction & fork methods by browser features ] </li></ul></ul></ul><ul><ul><ul><li>Zero Browser Sniffs </li></ul></ul></ul><ul><ul><ul><li>[ feature detection, feature testing, object inference ] </li></ul></ul></ul><ul><ul><ul><li>Framework Emulation </li></ul></ul></ul><ul><ul><ul><li>[ PrototypeJS at Beta, others later ] </li></ul></ul></ul><ul><ul><ul><li>Debug Friendly </li></ul></ul></ul><ul><ul><ul><li>[ console.log(fuse.Number(3).times); // times(callback, thisArg) ] </li></ul></ul></ul>Features
  33. 33. FuseJS <ul><ul><ul><li>Modular </li></ul></ul></ul><ul><ul><ul><li>[ less abstraction, custom builds ] </li></ul></ul></ul><ul><ul><ul><li>Selector Engines </li></ul></ul></ul><ul><ul><ul><li>[ Acme, DomQuery, NWMatcher , Peppy, Sizzle, Slick, Sly ] </li></ul></ul></ul><ul><ul><ul><li>Quirks mode support </li></ul></ul></ul><ul><ul><ul><li>[ dimensions, positioning ] </li></ul></ul></ul><ul><ul><ul><li>DOM + Event decorators </li></ul></ul></ul><ul><ul><ul><li>[ better 3rd party & browser support ] </li></ul></ul></ul><ul><ul><ul><li>Cross iframe compatible </li></ul></ul></ul><ul><ul><ul><li>[ fuse(iframeDoc).query('.widget') ] </li></ul></ul></ul>Features
  34. 34. FuseJS <ul><ul><ul><li>Enforce FIFO Event Observer Order </li></ul></ul></ul><ul><ul><ul><li>[ cross-browser and fixes edge cases ] </li></ul></ul></ul><ul><ul><ul><li>Back-Forward Cache </li></ul></ul></ul><ul><ul><ul><li>[ better performance between page navigation ] </li></ul></ul></ul><ul><ul><ul><li>No Expandos Added in IE </li></ul></ul></ul><ul><ul><ul><li>[ avoids unnecessary redraws ] </li></ul></ul></ul><ul><ul><ul><li>Method Generics </li></ul></ul></ul><ul><ul><ul><li>[ fuse.Array.slice(arr, 0) ] </li></ul></ul></ul><ul><ul><ul><li>Separation of DOM Properties & Attributes </li></ul></ul></ul><ul><ul><ul><li>[ fuse.dom.Element.plugin.readAttribute ] </li></ul></ul></ul>Features
  35. 35. FuseJS Performance [ lower score is better ]
  36. 36. FuseJS Performance [ lower score is better ]
  37. 37. FuseJS Performance [ IE8 - lower score is better ]
  38. 38. FuseJS Performance [ lower score is better ]
  39. 39. Links <ul><ul><ul><li>http://github.com/jdalton/fusejs </li></ul></ul></ul><ul><ul><ul><li>http://github.com/jdalton/fusebox </li></ul></ul></ul><ul><ul><ul><li>http://github.com/dperini/nwmatcher </li></ul></ul></ul><ul><ul><ul><li>http://fusejs.com </li></ul></ul></ul><ul><ul><ul><li>http://fusejs.com/nwmatcher/match/ </li></ul></ul></ul><ul><ul><ul><li>http://fusejs.com/prototypejs/speed/?css=yahoo http://javascript.nwbox.com/NWMatcher/release/test/css3-compat/ </li></ul></ul></ul><ul><li>Twitter: </li></ul><ul><li>@jdalton </li></ul><ul><li>@fusejs </li></ul><ul><li>Email: </li></ul><ul><li>[email_address] </li></ul>

×