SlideShare a Scribd company logo
Coding for  Performance Parental Advisory :  Hardcore Forking Action By  John-David Dalton  @jdalton  ▪  john@fusejs.com  ▪  http://allyoucanleet.com
function times(iterator, context) { $R( 0, this, true ) . each( iterator, context ) ; return this; } Reduce Abstraction 1.
function times(iterator, context) { var i = -1, length = this; while ( ++i < length )  iterator.call(context, i, i); return length; } Reduce Abstraction 2.
function times(iterator, context) { var i = -1, length = this; if ( context ) { while (++i < length)  iterator.call( context, i, i ) ; } else { while (++i < length)  iterator( i, i ) ; } return length; } Reduce Abstraction 3.
Test Before Tapping Dat Feature Testing   (Awesomest) Feature Detection   (Pretty good) Weak Object Inference   (Almost as bad as UA sniffing) User Agent Sniffing   (Just say no!) 4.
// true for Gecko and Webkit if ([ ][ ‘__proto__‘ ]  === Array.prototype   &&   { }[ '__proto__‘ ]  === Object.prototype ) { // test if it's writable and restorable var result, list = [], backup = list['__proto__']; list['__proto__'] = { }; result =  typeof   list.push === 'undefined' ; list['__proto__'] = backup; return result &&  typeof   list.push === 'function' ; } Feature Testing 5.
// Host objects can return type values that are different from their actual // data type. The objects we are concerned with usually return non-primitive // types of object, function, or unknown. // For example: // typeof document.createElement('div').offsetParent -> unknown // typeof document.createElement -> object // typeof Image.create -> string isHostType = (function() { var NON_HOST_TYPES =  { 'boolean': 1, 'number': 1, 'string': 1, 'undefined': 1 }; return function(object, property) { var type =  typeof   object[property] ; return  type  ===  'object'  ?  !! object[property]  :  ! NON_HOST_TYPES[ type ] ; }; })(); Feature Detection 6.
// true for IE return isHostType( window ,  'ActiveXObject' ); Feature Detection 7.
var xhr; // Assumed to be IE If ( document.fileSize ) {   xhr =  new ActiveXObject('Microsoft.XMLHTTP'); } else { xhr = new XMLHttpRequest(); } Weak Object Inference 8.
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 9.
var contains = function(element, descendant) { while ( descendant  =  descendant.parentNode ) { if (descendant === element) return true; } re tur n false; }; if ( isHostType(docEl, 'compareDocumentPosition') ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostType(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Fork like Robots 10.
var contains = function(element, descendant) { while ( descendant  =  descendant.parentNode ) { if (descendant === element) return true; } return false; }; if ( isHostType( docEl, 'compareDocumentPosition' ) ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostType(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Fork like Hobbits 11.
But don't fork Marsellus Wallace ! 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 ( isHostType ( docEl, 'contains' ) ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } 12.
Forking + Lazy Load plugin.getRelatedTarget =   function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget =  createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return  setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof this.raw.relatedTarget === 'undefined’ ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout':  node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin. getRelatedTarget  =  getRelatedTarget; return this.getRelatedTarget(); }; 13.
Forking + Lazy Load plugin.getRelatedTarget =  function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget =  createGetter( 'getRelatedTarget ' ,  value ); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if (typeof this.raw.relatedTarget === 'undefined') { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout':  node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } 14.
Forking + Lazy Load plugin.getRelatedTarget =  function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget =  createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return  setRelatedTarget( this ,   node   && fromElement(node) ) ; }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if (typeof this.raw.relatedTarget === 'undefined') { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout':  node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } 15.
Forking + Lazy Load getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return  setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof  this.raw.relatedTarget === 'undefined' ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout':  node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin.getRelatedTarget = getRelatedTarget; 16.
Forking + Lazy Load plugin.getRelatedTarget =  function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget =  createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return  setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof this.raw.relatedTarget === 'undefined’ ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout':  node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin. getRelatedTarget  =  getRelatedTarget ; return this.getRelatedTarget(); }; 17.
Memoize 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 )) ; } 18.
Nay Context // Prototype $$( ‘.foo’ ); // jQuery $( ‘.foo’ ); 19.
Yay Context // Prototype var panel =   $( ‘panel’ ); panel . select( ‘.foo’ ); // jQuery var panel =   $( ‘#panel’ ); panel .find( ‘.foo’ ); 20.
Event Delegation != Magic // Prototype usage $(‘myTable’).observe(‘click’, function( event ) { if ( event .findElement( ‘ td ’ )) { // do stuff } }); 21.
Minifiers Packer 3.1   (Old School, You’re my boy, Blue!) YUI Compressor   (Been around the block) Closure Compiler   (Googtastic) JSMin   (Ported to lots of languages) 22.
What’s Cool // code like this emit(‘I will be ’ +   ‘concated by ‘ +   ‘pirate magic’); // will be valmorphanize into emit(‘I will be concated by pirate magic’); 23.
Do Repeat use of the same variable names Store namespaced objects in variables Use variable lists Avoid compiled functions 24.
Do Not Become anal about semi-colons Replace all property names with variables Use short non-descriptive variable names Tug on Superman’s cape 25.
Hilarity Comics   by Patrick Alexander -- http://www.eegra.com/show/sub/do/browse/cat/comics/id/43
Hilarity Comics   by Patrick Alexander -- http://www.eegra.com/show/sub/do/browse/cat/comics/id/43
 
Links http://github.com/jdalton/fusejs http://developer.yahoo.com/yui/compressor/ http://code.google.com/closure/compiler/ http://www.crockford.com/javascript/jsmin.html http://github.com/rgrove/jsmin-php/ http://base2.googlecode.com/svn/trunk/src/apps/packer/packer.html http://code.google.com/p/base2/source/browse/#svn/trunk/src/apps/packer Twitter: @jdalton  @fusejs Email: [email_address]

More Related Content

What's hot (18)

PDF
Proxies are Awesome!
Brendan Eich
 
PPTX
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
PDF
Workshop 5: JavaScript testing
Visual Engineering
 
PPTX
Akka in-action
Raymond Roestenburg
 
PDF
Clean code with google guava jee conf
Igor Anishchenko
 
PPT
Advanced JavaScript
Stoyan Stefanov
 
KEY
連邦の白いヤツ 「Objective-C」
matuura_core
 
PPT
Advanced Javascript
Adieu
 
PPTX
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
OPITZ CONSULTING Deutschland
 
PDF
Functions, Types, Programs and Effects
Raymond Roestenburg
 
PPTX
Using Reflections and Automatic Code Generation
Ivan Dolgushin
 
PPTX
Advanced JavaScript Concepts
Naresh Kumar
 
PDF
Min-Maxing Software Costs
Konstantin Kudryashov
 
PDF
Google guava
t fnico
 
PDF
Min-Maxing Software Costs - Laracon EU 2015
Konstantin Kudryashov
 
PDF
Workshop 10: ECMAScript 6
Visual Engineering
 
PPTX
Workshop 1: Good practices in JavaScript
Visual Engineering
 
PDF
ES2015 workflows
Jarrod Overson
 
Proxies are Awesome!
Brendan Eich
 
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Workshop 5: JavaScript testing
Visual Engineering
 
Akka in-action
Raymond Roestenburg
 
Clean code with google guava jee conf
Igor Anishchenko
 
Advanced JavaScript
Stoyan Stefanov
 
連邦の白いヤツ 「Objective-C」
matuura_core
 
Advanced Javascript
Adieu
 
Test-driven JavaScript Development - OPITZ CONSULTING - Tobias Bosch - Stefa...
OPITZ CONSULTING Deutschland
 
Functions, Types, Programs and Effects
Raymond Roestenburg
 
Using Reflections and Automatic Code Generation
Ivan Dolgushin
 
Advanced JavaScript Concepts
Naresh Kumar
 
Min-Maxing Software Costs
Konstantin Kudryashov
 
Google guava
t fnico
 
Min-Maxing Software Costs - Laracon EU 2015
Konstantin Kudryashov
 
Workshop 10: ECMAScript 6
Visual Engineering
 
Workshop 1: Good practices in JavaScript
Visual Engineering
 
ES2015 workflows
Jarrod Overson
 

Similar to Web Optimization Summit: Coding for Performance (20)

PPTX
Ricky Bobby's World
Brian Lonsdorf
 
PPTX
Building High Perf Web Apps - IE8 Firestarter
Mithun T. Dhar
 
PDF
The Beauty of Java Script
Michael Girouard
 
PPTX
Maintainable JavaScript 2012
Nicholas Zakas
 
PDF
Building a JavaScript Library
jeresig
 
ZIP
YUI 3
Dav Glass
 
PDF
Performance patterns
Stoyan Stefanov
 
PPT
JSConf: All You Can Leet
johndaviddalton
 
PPTX
Building High Performance Web Applications and Sites
goodfriday
 
PDF
The Beauty Of Java Script V5a
rajivmordani
 
PDF
What's up with Prototype and script.aculo.us?
Christophe Porteneuve
 
KEY
10 Years of JavaScript
Mike de Boer
 
PDF
Ten useful JavaScript tips & best practices
Ankit Rastogi
 
KEY
JavaScript Growing Up
David Padbury
 
ZIP
Javascript Everywhere
Pascal Rettig
 
PDF
Ajax Tutorial
oscon2007
 
PDF
JavaScript: Patterns, Part 1
Chris Farrell
 
PDF
Object Oriented JavaScript
techwhizbang
 
PPT
JavaScript Basics
Mats Bryntse
 
PPTX
CT presentatie JQuery 7.12.11
virtualsciences41
 
Ricky Bobby's World
Brian Lonsdorf
 
Building High Perf Web Apps - IE8 Firestarter
Mithun T. Dhar
 
The Beauty of Java Script
Michael Girouard
 
Maintainable JavaScript 2012
Nicholas Zakas
 
Building a JavaScript Library
jeresig
 
YUI 3
Dav Glass
 
Performance patterns
Stoyan Stefanov
 
JSConf: All You Can Leet
johndaviddalton
 
Building High Performance Web Applications and Sites
goodfriday
 
The Beauty Of Java Script V5a
rajivmordani
 
What's up with Prototype and script.aculo.us?
Christophe Porteneuve
 
10 Years of JavaScript
Mike de Boer
 
Ten useful JavaScript tips & best practices
Ankit Rastogi
 
JavaScript Growing Up
David Padbury
 
Javascript Everywhere
Pascal Rettig
 
Ajax Tutorial
oscon2007
 
JavaScript: Patterns, Part 1
Chris Farrell
 
Object Oriented JavaScript
techwhizbang
 
JavaScript Basics
Mats Bryntse
 
CT presentatie JQuery 7.12.11
virtualsciences41
 
Ad

Recently uploaded (20)

PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
DOCX
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Ad

Web Optimization Summit: Coding for Performance

  • 1. Coding for Performance Parental Advisory : Hardcore Forking Action By John-David Dalton @jdalton ▪ [email protected] ▪ http://allyoucanleet.com
  • 2. function times(iterator, context) { $R( 0, this, true ) . each( iterator, context ) ; return this; } Reduce Abstraction 1.
  • 3. function times(iterator, context) { var i = -1, length = this; while ( ++i < length ) iterator.call(context, i, i); return length; } Reduce Abstraction 2.
  • 4. function times(iterator, context) { var i = -1, length = this; if ( context ) { while (++i < length) iterator.call( context, i, i ) ; } else { while (++i < length) iterator( i, i ) ; } return length; } Reduce Abstraction 3.
  • 5. Test Before Tapping Dat Feature Testing (Awesomest) Feature Detection (Pretty good) Weak Object Inference (Almost as bad as UA sniffing) User Agent Sniffing (Just say no!) 4.
  • 6. // true for Gecko and Webkit if ([ ][ ‘__proto__‘ ] === Array.prototype && { }[ '__proto__‘ ] === Object.prototype ) { // test if it's writable and restorable var result, list = [], backup = list['__proto__']; list['__proto__'] = { }; result = typeof list.push === 'undefined' ; list['__proto__'] = backup; return result && typeof list.push === 'function' ; } Feature Testing 5.
  • 7. // Host objects can return type values that are different from their actual // data type. The objects we are concerned with usually return non-primitive // types of object, function, or unknown. // For example: // typeof document.createElement('div').offsetParent -> unknown // typeof document.createElement -> object // typeof Image.create -> string isHostType = (function() { var NON_HOST_TYPES = { 'boolean': 1, 'number': 1, 'string': 1, 'undefined': 1 }; return function(object, property) { var type = typeof object[property] ; return type === 'object' ? !! object[property] : ! NON_HOST_TYPES[ type ] ; }; })(); Feature Detection 6.
  • 8. // true for IE return isHostType( window , 'ActiveXObject' ); Feature Detection 7.
  • 9. var xhr; // Assumed to be IE If ( document.fileSize ) { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } else { xhr = new XMLHttpRequest(); } Weak Object Inference 8.
  • 10. 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 9.
  • 11. var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) return true; } re tur n false; }; if ( isHostType(docEl, 'compareDocumentPosition') ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostType(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Fork like Robots 10.
  • 12. var contains = function(element, descendant) { while ( descendant = descendant.parentNode ) { if (descendant === element) return true; } return false; }; if ( isHostType( docEl, 'compareDocumentPosition' ) ) { contains = function(element, descendant) { /* DOCUMENT_POSITION_CONTAINS = 0x08 */ return (descendant .compareDocumentPosition(element) & 8) === 8; }; } else if ( isHostType(docEl, 'contains') ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } Fork like Hobbits 11.
  • 13. But don't fork Marsellus Wallace ! 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 ( isHostType ( docEl, 'contains' ) ) { contains = function(element, descendant) { return element !== descendant && element.contains(descendant); }; } 12.
  • 14. Forking + Lazy Load plugin.getRelatedTarget = function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget = createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof this.raw.relatedTarget === 'undefined’ ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout': node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin. getRelatedTarget = getRelatedTarget; return this.getRelatedTarget(); }; 13.
  • 15. Forking + Lazy Load plugin.getRelatedTarget = function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget = createGetter( 'getRelatedTarget ' , value ); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if (typeof this.raw.relatedTarget === 'undefined') { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout': node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } 14.
  • 16. Forking + Lazy Load plugin.getRelatedTarget = function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget = createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget( this , node && fromElement(node) ) ; }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if (typeof this.raw.relatedTarget === 'undefined') { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout': node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } 15.
  • 17. Forking + Lazy Load getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof this.raw.relatedTarget === 'undefined' ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout': node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin.getRelatedTarget = getRelatedTarget; 16.
  • 18. Forking + Lazy Load plugin.getRelatedTarget = function getRelatedTarget() { var setRelatedTarget = function(object, value) { object.getRelatedTarget = createGetter('getRelatedTarget', value); return value; }, getRelatedTarget = function getRelatedTarget() { var node = this.raw && this.raw.relatedTarget; return setRelatedTarget(this, node && fromElement(node)); }; // fired events have no raw if (!this.raw) { return setRelatedTarget(this, null); } // for IE if ( typeof this.raw.relatedTarget === 'undefined’ ) { getRelatedTarget = function getRelatedTarget() { var node = null, event = this.raw; switch (event && event.type) { case 'mouseover': node = fromElement(event.fromElement); case 'mouseout': node = fromElement(event.toElement); } return setRelatedTarget(this, node); }; } plugin. getRelatedTarget = getRelatedTarget ; return this.getRelatedTarget(); }; 17.
  • 19. Memoize 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 )) ; } 18.
  • 20. Nay Context // Prototype $$( ‘.foo’ ); // jQuery $( ‘.foo’ ); 19.
  • 21. Yay Context // Prototype var panel = $( ‘panel’ ); panel . select( ‘.foo’ ); // jQuery var panel = $( ‘#panel’ ); panel .find( ‘.foo’ ); 20.
  • 22. Event Delegation != Magic // Prototype usage $(‘myTable’).observe(‘click’, function( event ) { if ( event .findElement( ‘ td ’ )) { // do stuff } }); 21.
  • 23. Minifiers Packer 3.1 (Old School, You’re my boy, Blue!) YUI Compressor (Been around the block) Closure Compiler (Googtastic) JSMin (Ported to lots of languages) 22.
  • 24. What’s Cool // code like this emit(‘I will be ’ + ‘concated by ‘ + ‘pirate magic’); // will be valmorphanize into emit(‘I will be concated by pirate magic’); 23.
  • 25. Do Repeat use of the same variable names Store namespaced objects in variables Use variable lists Avoid compiled functions 24.
  • 26. Do Not Become anal about semi-colons Replace all property names with variables Use short non-descriptive variable names Tug on Superman’s cape 25.
  • 27. Hilarity Comics by Patrick Alexander -- http://www.eegra.com/show/sub/do/browse/cat/comics/id/43
  • 28. Hilarity Comics by Patrick Alexander -- http://www.eegra.com/show/sub/do/browse/cat/comics/id/43
  • 29.  
  • 30. Links http://github.com/jdalton/fusejs http://developer.yahoo.com/yui/compressor/ http://code.google.com/closure/compiler/ http://www.crockford.com/javascript/jsmin.html http://github.com/rgrove/jsmin-php/ http://base2.googlecode.com/svn/trunk/src/apps/packer/packer.html http://code.google.com/p/base2/source/browse/#svn/trunk/src/apps/packer Twitter: @jdalton @fusejs Email: [email_address]