SlideShare a Scribd company logo
1 of 68
jQuery Anti-Patterns for
Performance &
Compression
Paul Irish
NC JavaScript Camp ’10
jQuery Anti-Patterns for
Performance &
Compression
Paul Irish
NC JavaScript Camp ’10
Me.
Interaction Designer at Molecular, Inc.
jQuery Team Member - Dev. Relations


     @paul_irish
http://paulirish.com Front-end development blog
http://aurgasm.us Eclectic music blog
Performance
Performance
wassup shawty? how u doin’
                  Taskspeed Test Lines of Code
200



150



100



50



 0
      YUI   Dojo 1.3.1 Dojo 1.2.3 Qooxdoo MooTools Prototype.js   jQuery   PureDOM
Oft cited best practices
 Cache length during loops
 Cache your selections
 Leverage documentFragment
 Append new content outside the loop
Oft cited best practices
 Cache length during loops
// appending inside. bad.
$.each(reallyLongArray, function(count, item) {
 Cache your selections
    var newLI = '<li>' + item + '</li>';
    $('#ballers').append(newLI);
 Leverage documentFragment
});
 Append new content outside the loop
// documentFragment off-DOM
var frag = document.createDocumentFragment();
$.each(reallyLongArray, function(count, item) {
    var newLI = '<li>' + item + '</li>';
    frag.appendChild(newLI[0]);
});
$('#ballers')[0].appendChild(frag);
var newLI = '<li>' + item + '</li>';
      $('#ballers').append(newLI);

Oft cited best practices
});

// documentFragment off-DOM
var frag = document.createDocumentFragment();
 Cache length during loops
$.each(reallyLongArray, function(count, item) {
    var newLI = '<li>' + item + '</li>';
 Cache your selections
    frag.appendChild(newLI[0]);
});
 Leverage documentFragment
$('#ballers')[0].appendChild(frag);

 Append new content outside the loop
// string concatenate and set innerHTML
var myhtml = '';
$.each(reallyLongArray, function(count, item) {
    myhtml += '<li>' + item + '</li>';
});
$('#ballers').html(myhtml);
Keep things DRY

 If you’re repeating
 yourself, you’re doing it
 wrong
Moar DRY plz?

if ($ventfade.data('currently') != 'showing') {
  $ventfade.stop();
}
if ($venthover.data('currently') != 'showing') {
  $venthover.stop();
}
if ($spans.data('currently') != 'showing') {
  $spans.stop();
}



                       from http://mt-ventures.com/_js/global.js
All clean! Thx

var elems = [$ventfade,$venthover,$spans];

$.each(elems,function(k,v){
    if (v.data('currently') != 'showing'){
         v.stop();
    }
})
Architecture Anti-Patterns
 Anonymous functions bound everywhere suck
$(document).ready(function(){
    ...
    $('#magic').click(function(e){

            $('#yayeffects').slideUp(function(){
                ...
            });
      });

      $('#happiness').load(url+' #unicorns',function(){
          ...
      })
});
Architecture - Object Literal
var PI = {
  onReady   : function(){
      ...
      $('#magic').click(PI.candyMtn);
      $('#happiness').load(url+' #unicorns',PI.unicornCb);
  },
  candyMtn : function(e){
     $('#yayeffects').slideUp(PI.slideCb);
  },
  slideCb   : function(){
      ...
  },
  unicornCb : function(){
      ...
  }
}

$(document).ready(PI.onReady);
Architecture - Object Literal
 Advantages:
  Easier to navigate and discuss
  Profilers give you actual names to work with
  You can execute these from firebug console
  You can write unit tests against them
Anti-Pattern: The requery
// create and append your element
$(document.body).append("<div class='baaron'/>");
// requery to bind stuff
$("div.baaron").click(function(){});




// better:
// swap to appendTo to hold your elem
$("<div class='baaron'/>")
    .appendTo(document.body)
    .click(function(){});
$(‘#whats .the’,context)
This is not the .context property

  // find all stylesheets in the body
  var bodySheets = $('style',document.body);
  bodySheets.context // ==> BODY element


  Ignore that for the moment, I know no one that’s
  found a use
$(‘#whats .the’,context)
 Never pass it a selector string. Ever.
 No performance gain vs $(root).find(selector)

   var arms = $('div.robotarm', '#container');
   // instead do:
   var arms = $('#container').find('div.robotarm');
$(‘#whats .the’,context)
 You typically pass it this, but it’s purely a
 convenience to avoid find()

 $('form.comments',this).submit(captureSubmit);
 // exact same as
 $(this).find('form.comments').submit(captureSubmit);


 Which is more readable?

$('.reply_form', $(this).closest('.comment')).hide();

$(this).closest('.comment').find('.reply_form').hide();
The Crowd Say Bo Selector
Come on, my selector
Selector engines have come a long, long way.
Come on, my selector
Selector engines have come a long, long way.
Come on, my selector
Engines work in different ways
Top-down, bottom-up, function creation, other crazy shit


// from NWMatcher:

// selecting '.outmost #outer span'


T=e.nodeName;if(T=="SPAN"||T=="span")
{while((e=e.parentNode)&&e.nodeType==1)
{if((n=e.getAttributeNode("id"))&&n.value=="outer")
{if((e=e.parentNode)&&e.nodeType==1)
{C=e.className;if(C&&(" "+C+" ").indexOf(" outmost ")>-1)
{r[X++]=N;continue main;}}}}}
Selector engines, parse direction
 Left to right (Top-down)      Right to left (Bottom-up)

        Mootools                           Sizzle

           Sly                             YUI 3

         Peppy                         NWMatcher

       Dojo Acme

         Ext JS

      Prototype.js
                        details: http://alexsexton.com/selectors/
Selector engines, parse direction
  div.data table.attendees .gonzalez

 Left to right (Top-down)      Right to left (Bottom-up)

        Mootools                           Sizzle

           Sly                             YUI 3

         Peppy                         NWMatcher

       Dojo Acme

         Ext JS

      Prototype.js
                        details: http://alexsexton.com/selectors/
Selector engines, parse direction
 Left to right (Top-down)      Right to left (Bottom-up)

        Mootools                           Sizzle

           Sly                             YUI 3

         Peppy                         NWMatcher

       Dojo Acme

         Ext JS

      Prototype.js
                        details: http://alexsexton.com/selectors/
Selector engines, parse direction
 Left to right (Top-down)      Right to left (Bottom-up)

        Mootools                           Sizzle

           Sly                             YUI 3

         Peppy                         NWMatcher

       Dojo Acme                 querySelectorAll (qSA)

         Ext JS

      Prototype.js
                        details: http://alexsexton.com/selectors/
Selector Optimization
 Specific on the right, light on the left

 // let's find scott
 div.data .gonzalez

 // specific on right, light on the left
 .data td.gonzalez



 tag.class if possible on your right-most selector.
 just tag or just .class on left.
Selector Optimization
 Of course, descending from an #id is best


// basic #id-based selector
var arms = $('#container div.robotarm');

// hyper-optimized #id case first, then find:
var arms = $('#container').find('div.robotarm');
Selector Optimization
 Don’t be needlessly specific

 // let's find scott
 .data table.attendees td.gonzalez

 // better: drop the middle
 .data td.gonzalez




A flatter DOM helps, so move to HTML5
   Also a wider range of tags speeds up filters
Selector Optimization
 Avoid the universal selector
 Avoid the implied universal selector

 $('.buttons > *') // terribly costly
 $('.buttons').children() // much better




 $('.gender :radio') // implied universal
 $('.gender *:radio') // exact same, explicit now
 $('.gender input:radio') // much better
Selector Optimization
 Google PageSpeed’s efficient selectors analysis
 MDC: Writing Efficient CSS
  https://developer.mozilla.org/en/Writing_Efficient_CSS

 Benchmark.js
  http://code.paulirish.com/sandbox/benchmark.js
Event Delegation
 function delegate(type, delegate, handler) {
     return $(document).bind(type, function(event) {
         var target = $(event.target);
         if (target.is(delegate)) {
             return handler.apply(target, arguments);
         }
     });
 }

 delegate('click','td.jehl',createRockstar);

 // and with live():
 $('td.jehl').live('click',createRockstar);
Event Delegation
live() isn’t just for dynamic content
Speeds up page load
  Only one event handler is bound vs many
Good for >3 elements all getting the same handler

 // using live(), skipping selection on load
 var jqElem = $(document);
 jqElem.selector = 'li.ui';
 jqElem.live('dblclick', dblhandler);
Event Delegation
live() isn’t just for dynamic content
Speeds up page load
  Only one event handler is bound vs many
Good for >3 elements all getting the same handler

 // using live(), skipping selection on load
 var jqElem = $(document);
 jqElem.selector = 'li.ui';
 jqElem.live('dblclick', dblhandler);
Event Delegation
   delegate() bakes in huge performance gains
   explicit context reduces overhead by ~80%
   Use it instead of live() if possible


// awkward but equivalent
$('a.trigger',$('#container')[0]).live('click',handlerFn)

// so damn fine
$('#container').delegate('click','a.trigger',handlerFn)
Event Delegation                               new
                                                        in
                                                1.4
                                                    .2!
   delegate() bakes in huge performance gains
   explicit context reduces overhead by ~80%
   Use it instead of live() if possible


// awkward but equivalent
$('a.trigger',$('#container')[0]).live('click',handlerFn)

// so damn fine
$('#container').delegate('click','a.trigger',handlerFn)
The DOM is slow
Pull elements off the DOM while you toy with them

var table = $('#some-table');
var parent = table.parent();

table.detach();
table.addLotsAndLotsOfRows();
parent.append(table);
The DOM is slow
Pull elements off the DOM while you toy with them

var table = $('#some-table');
var parent = table.parent();
                                         new
table.detach();
                                       in 1
                                            .4
table.addLotsAndLotsOfRows();
parent.append(table);
Minimize DOM touches
       Use classes, but if a style change user-selected:

  jQuery('a.swedberg').css('color', '#BADA55');

  jQuery('<style type="text/css"> a.swedberg { color: BADA55; } </style>')
    .appendTo('head');



                                                         Timings for X elements
3000
2250                                                     (1000 iterations)

1500                                                          css()
                                                              style tag
750
  0
       1        5          10          20           50
Minimize DOM touches
Don’t treat jQuery as a Black Box
 Use the source as your documentation
 Add this to your bookmark bar, NOW!
   http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js
   http://bit.ly/jqsource
 Determine which are convenience methods:
   getScript: function( url, callback ) {
       return jQuery.get(url, null, callback, "script");
   },
   getJSON: function( url, data, callback ) {
       return jQuery.get(url, data, callback, "json");
   },
Don’t treat jQuery as a Black Box
 Learn the lesser-known methods
   map(), slice(), stop(), (de)queue(),
   prevAll(), pushStack(), inArray() , etc

 // index() in jQuery <= 1.3.2
 $('#rdworth').parent().children().index( $('#rdworth')[0] )

 // using prevAll() is 10% faster (also sexier)
 $('#rdworth').prevAll().length

 // in jQuery 1.4
 $('#rdworth').index()
Don’t act on absent elements
 jQuery is very kind and doesn’t throw errors at you
 Don’t assume it’s just fine to do

   $('#doesntexist').slideUp()
   // this will execute genFx(), speed() and animate()
   //   before it hits an each()



 jQuery UI widgets have a lot of overhead you’ll hit
Don’t act on absent elements

 jQuery.fn.doOnce = function(func){
     this.length && func.apply(this);
     return this;
 }


 $('li.cartitems').doOnce(function(){
     // make it ajax! o/
 });
Don’t act on absent elements


 $.fn.plugin = function(opts){
    if(!this.length) return this;
    var opts = $.extend(......
    ...
    return this.each(...
Setter Methods



view-source:setters.js
new
New Element Creation                        1.4
                                                !
                                                  in

jQuery("<div/>", {
    id: "foo",
    rel : "something"
    css: {
        height: "50px",
        width: "50px",
        color: "blue",
        backgroundColor: "#ccc"
    },
    click: function() {
       $(this).css("backgroundColor", "red");
    }
}).appendTo("body");
new
eq(), first(), last()                 1.4
                                         !
                                           in




var lastelem = $elems.eq(-1); // get() too!



$('#nav li:first') === $('#nav li').first()

$('#nav li:last') === $('#nav li').last()
Data()

// regular:
$(elem).data(key,value);

// omg like 10x faster:
$.data(elem,key,value);
Compression
Compression
YUI Compressor
  Sits on Rhino.
Comments, whitespace, variable replacement

//it already does these micro-optimizations:
object['prop'] ==> object.prop
{'key':123} ==> {key:123}
'jon's apostophes' ==> "jon's apostrophes"
'bigass ' + 'string' ==> 'bigass string'
Variable definition

// old 'n busted            // new hotness
var test1 = 1;              var test1 = 1,
var test2 = function() {        test2 = function() {
    // function code                // function code
};                              },
var test3 = test2(test1);       test3 = test2(test1);
Munge the primitives
Define shortcuts at the top of your scope
  Good for both compression and scope chain traversal


var TRUE = true,
    FALSE = false,
    NULL = null,
    window = self,
    undefined = undefined;
Munge the primitives
Define shortcuts at the top of your scope
  Good for both compression and scope chain traversal


var TRUE = true,
    FALSE = false,
    NULL = null,
    window = self,
    undefined;
    undefined = undefined;
Munge the primitives

(function(){
   var window = this, document = document,
undefined;
   /* code */
})();


(function(window, document, undefined){
   /* code */
})(this,this.document);
var str=‘Let’s put this into action’

 // html.no-js html>
 <!doctype ==> html.js
 var elem = document.getElementsByTagName('html')[0];
 elem.className = elem.className.replace('no-js','js');
 <html class="no-js">
 // quicker reference, safer replace
 <head>
 var elem = document.documentElement;
 elem.className = elem.className.replace(/bno-jsb/,'js');
    <script>
 // one// change the html class to 'js'
        line ftw!
       // in the head, no FOUC
 document.documentElement.className =
 document.documentElement.className.replace(/bno-jsb/,
    </script>
 'js');
 </body>
 // shorter with a self-executing anonymous function
 (function(B){B.className=B.className.replace(/bno-jsb/,
var str=‘Let’s put this into action’

 // html.no-js ==> html.js
 var elem = document.getElementsByTagName('html')[0];
 elem.className = elem.className.replace('no-js','js');

 // quicker reference, safer replace
 var elem = document.documentElement;
 elem.className = elem.className.replace(/bno-jsb/,'js');

 // one line ftw!
 document.documentElement.className =
 document.documentElement.className.replace(/bno-jsb/,
 'js');

 // shorter with a self-executing anonymous function
 (function(B){B.className=B.className.replace(/bno-jsb/,
// html.no-js ==> html.js
var elem = document.getElementsByTagName('html')[0];

var str=‘Let’s put this into action’
elem.className = elem.className.replace('no-js','js');

// quicker reference, safer replace
var elem = document.documentElement;
elem.className = elem.className.replace(/bno-jsb/,'js');

// one line ftw!
document.documentElement.className =
document.documentElement.className.replace(/bno-jsb/,
'js');

// shorter with a self-executing anonymous function
(function(B){B.className=B.className.replace(/bno-jsb/,
'js')})(document.documentElement);

// pass className, object string notation
(function(H,C){H[C]=H[C].replace(/bno-jsb/,'js')})
(document.documentElement,'className')
Conditionals


// old 'n busted
if ( type === 'foo' || type === 'bar' ) {}

// regex test
if ( /^(foo|bar)$/.test(type) ) {}

// obj literal lookup (smaller if <5 items)
if ( ({foo:1,bar:1})[type] ) {}
Logic and Ternary operands
// basic function detection
document.querySelectorAll && document.querySelectorAll('a:nth-child(2)')

// assignment is legal, but it evaluates to the right expression
callback && (isCallbackCalled = true) && callback(returnVal);

// call or cache the callback function
(isCallbackCalled || returnVal) ? fn(returnVal) : (callback = fn);

// inline function calls
isToday('Saturday') && Math.round(Math.random()) && $('#winnar').show()

// if JSON2.js or Native JSON is present, otherwise eval.
data = window.JSON && JSON.parse(data) || eval('('+data +')');
Write maintainable code
                   As a developer,

       you should work first   and foremost
            for the user of your products.
  The second most important person to work for is
        the developer that takes over from you.
                                   - Christian Heilmann
Comments
/*!
 * Will not be removed by YUI Compressor
 */



// for quick toggling on and off:
/* */
 aaaahYeah();
/* */

/* * /
 ohHellNo();
/* */
Compression Tools
CompressorRater
  http://compressorrater.thruhere.net/
YUI Compressor front-end
  http://refresh-sf.com/yui/
Thanks, ya’ll.
 Slides at http://paulirish.com/perf


      @paul_irish




thx:
 Alex Sexton, Ben Alman, Adam Sontag,
 James Padolsey, temp01, #jquery on Freenode
todo
shadow effect to code samples
more context research and this: http://
groups.google.com/group/jquery-dev/msg/
b4b7935a4013dfe7 and http://ispeakwebstuff.co.uk/
web-design-development-tutorials/clever-jquery-
selectors/
`
    // pngfix for IE6
    // e.g. FL.pngfix('img.bigProdShot,a.thumb');
    pngfix : function(sel){
      // conditional comments for inclusion of that js.
      if (typeof DD_belatedPNG == 'undefined'){ return;
      } else {
        // delay pngfix until window onload
        $(window).load(function(){ $(sel).each(function()
    { DD_belatedPNG.fixPng(arguments[1]); }); });
      }
    } // end of FL.pngfix()

More Related Content

What's hot

CSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
CSW2017 Qiang li zhibinhu_meiwang_dig into qemu securityCSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
CSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
CanSecWest
 
Adventures in Femtoland: 350 Yuan for Invaluable Fun
Adventures in Femtoland: 350 Yuan for Invaluable FunAdventures in Femtoland: 350 Yuan for Invaluable Fun
Adventures in Femtoland: 350 Yuan for Invaluable Fun
arbitrarycode
 
8.1.intro unix
8.1.intro unix8.1.intro unix
8.1.intro unix
southees
 
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Mario Heiderich
 

What's hot (20)

Android enterpriseで実現できる端末管理の世界
Android enterpriseで実現できる端末管理の世界Android enterpriseで実現できる端末管理の世界
Android enterpriseで実現できる端末管理の世界
 
XSS Magic tricks
XSS Magic tricksXSS Magic tricks
XSS Magic tricks
 
Postman & API Testing by Amber Race
Postman & API Testing by Amber RacePostman & API Testing by Amber Race
Postman & API Testing by Amber Race
 
SSRF vs. Business-critical applications. XXE tunneling in SAP
SSRF vs. Business-critical applications. XXE tunneling in SAPSSRF vs. Business-critical applications. XXE tunneling in SAP
SSRF vs. Business-critical applications. XXE tunneling in SAP
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
Automated testing with Cypress
Automated testing with CypressAutomated testing with Cypress
Automated testing with Cypress
 
Nikto
NiktoNikto
Nikto
 
経験を語るメディアとしての パターン・ランゲージ
経験を語るメディアとしての パターン・ランゲージ経験を語るメディアとしての パターン・ランゲージ
経験を語るメディアとしての パターン・ランゲージ
 
Automated UI Testing
Automated UI TestingAutomated UI Testing
Automated UI Testing
 
Neat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protectionNeat tricks to bypass CSRF-protection
Neat tricks to bypass CSRF-protection
 
64 Methods for Mimikatz Execution
64 Methods for Mimikatz Execution64 Methods for Mimikatz Execution
64 Methods for Mimikatz Execution
 
CSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
CSW2017 Qiang li zhibinhu_meiwang_dig into qemu securityCSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
CSW2017 Qiang li zhibinhu_meiwang_dig into qemu security
 
Adventures in Femtoland: 350 Yuan for Invaluable Fun
Adventures in Femtoland: 350 Yuan for Invaluable FunAdventures in Femtoland: 350 Yuan for Invaluable Fun
Adventures in Femtoland: 350 Yuan for Invaluable Fun
 
初めて解析したマルウェアはMIPSアーキテクチャ
初めて解析したマルウェアはMIPSアーキテクチャ初めて解析したマルウェアはMIPSアーキテクチャ
初めて解析したマルウェアはMIPSアーキテクチャ
 
Samba4を「ふつうに」使おう!
Samba4を「ふつうに」使おう!Samba4を「ふつうに」使おう!
Samba4を「ふつうに」使おう!
 
8.1.intro unix
8.1.intro unix8.1.intro unix
8.1.intro unix
 
Reverse of DPAPI - BlackHat DC 2010
Reverse of DPAPI - BlackHat DC 2010Reverse of DPAPI - BlackHat DC 2010
Reverse of DPAPI - BlackHat DC 2010
 
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
 
OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA Testers
 
How to Shot Web - Jason Haddix at DEFCON 23 - See it Live: Details in Descrip...
How to Shot Web - Jason Haddix at DEFCON 23 - See it Live: Details in Descrip...How to Shot Web - Jason Haddix at DEFCON 23 - See it Live: Details in Descrip...
How to Shot Web - Jason Haddix at DEFCON 23 - See it Live: Details in Descrip...
 

Viewers also liked

An Overview of HTML5 Storage
An Overview of HTML5 StorageAn Overview of HTML5 Storage
An Overview of HTML5 Storage
Paul Irish
 
Trabalho sobre Queimaduras
Trabalho sobre QueimadurasTrabalho sobre Queimaduras
Trabalho sobre Queimaduras
Rui Alves
 

Viewers also liked (20)

jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)
 
Client-Side Packages
Client-Side PackagesClient-Side Packages
Client-Side Packages
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
EPAM. Hadoop MR streaming in Hive
EPAM. Hadoop MR streaming in HiveEPAM. Hadoop MR streaming in Hive
EPAM. Hadoop MR streaming in Hive
 
Finite State Machines and C++
Finite State Machines and C++Finite State Machines and C++
Finite State Machines and C++
 
Writing Scalable React Applications: Introduction
Writing Scalable React Applications: IntroductionWriting Scalable React Applications: Introduction
Writing Scalable React Applications: Introduction
 
How to Write UI Automated Tests
How to Write UI Automated TestsHow to Write UI Automated Tests
How to Write UI Automated Tests
 
Organization of Automated Testing
Organization of Automated TestingOrganization of Automated Testing
Organization of Automated Testing
 
CAP theorem and distributed systems
CAP theorem and distributed systemsCAP theorem and distributed systems
CAP theorem and distributed systems
 
[Tech Talks] Typesafe Stack Introduction
[Tech Talks] Typesafe Stack Introduction[Tech Talks] Typesafe Stack Introduction
[Tech Talks] Typesafe Stack Introduction
 
An Overview of HTML5 Storage
An Overview of HTML5 StorageAn Overview of HTML5 Storage
An Overview of HTML5 Storage
 
Introduction to Serverless
Introduction to ServerlessIntroduction to Serverless
Introduction to Serverless
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript Performance
 
Trabalho sobre Queimaduras
Trabalho sobre QueimadurasTrabalho sobre Queimaduras
Trabalho sobre Queimaduras
 
NGINX Microservices Reference Architecture: Ask Me Anything
NGINX Microservices Reference Architecture: Ask Me AnythingNGINX Microservices Reference Architecture: Ask Me Anything
NGINX Microservices Reference Architecture: Ask Me Anything
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
Docker for Java Developers
Docker for Java DevelopersDocker for Java Developers
Docker for Java Developers
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
React js
React jsReact js
React js
 

Similar to jQuery Anti-Patterns for Performance & Compression

Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.
Peter Higgins
 
Jquery Best Practices
Jquery Best PracticesJquery Best Practices
Jquery Best Practices
brinsknaps
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
girish82
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
smueller_sandsmedia
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
Andy Peterson
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
Justin Cataldo
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
Jacob Kaplan-Moss
 

Similar to jQuery Anti-Patterns for Performance & Compression (20)

Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.
 
Jquery Best Practices
Jquery Best PracticesJquery Best Practices
Jquery Best Practices
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricks
 
jQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't KnowjQuery - 10 Time-Savers You (Maybe) Don't Know
jQuery - 10 Time-Savers You (Maybe) Don't Know
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascript
 
Javascript in Plone
Javascript in PloneJavascript in Plone
Javascript in Plone
 
jQuery Basic API
jQuery Basic APIjQuery Basic API
jQuery Basic API
 
jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQuery
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Ember background basics
Ember background basicsEmber background basics
Ember background basics
 
J query training
J query trainingJ query training
J query training
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
 
jQuery Foot-Gun Features
jQuery Foot-Gun FeaturesjQuery Foot-Gun Features
jQuery Foot-Gun Features
 

More from Paul Irish (8)

Progressive Advancement, by way of progressive enhancement
Progressive Advancement, by way of progressive enhancementProgressive Advancement, by way of progressive enhancement
Progressive Advancement, by way of progressive enhancement
 
webfonts & @font-face :: in brief
webfonts & @font-face :: in briefwebfonts & @font-face :: in brief
webfonts & @font-face :: in brief
 
Progressive Advancement in Web8
Progressive Advancement in Web8Progressive Advancement in Web8
Progressive Advancement in Web8
 
Squeezing The Best Out Of Webfonts
Squeezing The Best Out Of WebfontsSqueezing The Best Out Of Webfonts
Squeezing The Best Out Of Webfonts
 
Modernizr - Detecting HTML5 and CSS3 support
Modernizr - Detecting HTML5 and CSS3 supportModernizr - Detecting HTML5 and CSS3 support
Modernizr - Detecting HTML5 and CSS3 support
 
Employing Custom Fonts
Employing Custom FontsEmploying Custom Fonts
Employing Custom Fonts
 
Practical Design Solutions from Japan
Practical Design Solutions from JapanPractical Design Solutions from Japan
Practical Design Solutions from Japan
 
Rich Typography Options For The Web - or - Why sIFR is Dead in 2009
Rich Typography Options For The Web - or - Why sIFR is Dead in 2009Rich Typography Options For The Web - or - Why sIFR is Dead in 2009
Rich Typography Options For The Web - or - Why sIFR is Dead in 2009
 

Recently uploaded

CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
Wonjun Hwang
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc
 
Microsoft BitLocker Bypass Attack Method.pdf
Microsoft BitLocker Bypass Attack Method.pdfMicrosoft BitLocker Bypass Attack Method.pdf
Microsoft BitLocker Bypass Attack Method.pdf
Overkill Security
 

Recently uploaded (20)

State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
Navigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi DaparthiNavigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi Daparthi
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Microsoft BitLocker Bypass Attack Method.pdf
Microsoft BitLocker Bypass Attack Method.pdfMicrosoft BitLocker Bypass Attack Method.pdf
Microsoft BitLocker Bypass Attack Method.pdf
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
The Ultimate Prompt Engineering Guide for Generative AI: Get the Most Out of ...
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 

jQuery Anti-Patterns for Performance & Compression

  • 1. jQuery Anti-Patterns for Performance & Compression Paul Irish NC JavaScript Camp ’10
  • 2. jQuery Anti-Patterns for Performance & Compression Paul Irish NC JavaScript Camp ’10
  • 3. Me. Interaction Designer at Molecular, Inc. jQuery Team Member - Dev. Relations @paul_irish http://paulirish.com Front-end development blog http://aurgasm.us Eclectic music blog
  • 6. wassup shawty? how u doin’ Taskspeed Test Lines of Code 200 150 100 50 0 YUI Dojo 1.3.1 Dojo 1.2.3 Qooxdoo MooTools Prototype.js jQuery PureDOM
  • 7. Oft cited best practices Cache length during loops Cache your selections Leverage documentFragment Append new content outside the loop
  • 8. Oft cited best practices Cache length during loops // appending inside. bad. $.each(reallyLongArray, function(count, item) { Cache your selections var newLI = '<li>' + item + '</li>'; $('#ballers').append(newLI); Leverage documentFragment }); Append new content outside the loop // documentFragment off-DOM var frag = document.createDocumentFragment(); $.each(reallyLongArray, function(count, item) { var newLI = '<li>' + item + '</li>'; frag.appendChild(newLI[0]); }); $('#ballers')[0].appendChild(frag);
  • 9. var newLI = '<li>' + item + '</li>'; $('#ballers').append(newLI); Oft cited best practices }); // documentFragment off-DOM var frag = document.createDocumentFragment(); Cache length during loops $.each(reallyLongArray, function(count, item) { var newLI = '<li>' + item + '</li>'; Cache your selections frag.appendChild(newLI[0]); }); Leverage documentFragment $('#ballers')[0].appendChild(frag); Append new content outside the loop // string concatenate and set innerHTML var myhtml = ''; $.each(reallyLongArray, function(count, item) { myhtml += '<li>' + item + '</li>'; }); $('#ballers').html(myhtml);
  • 10. Keep things DRY If you’re repeating yourself, you’re doing it wrong
  • 11. Moar DRY plz? if ($ventfade.data('currently') != 'showing') { $ventfade.stop(); } if ($venthover.data('currently') != 'showing') { $venthover.stop(); } if ($spans.data('currently') != 'showing') { $spans.stop(); } from http://mt-ventures.com/_js/global.js
  • 12. All clean! Thx var elems = [$ventfade,$venthover,$spans]; $.each(elems,function(k,v){ if (v.data('currently') != 'showing'){ v.stop(); } })
  • 13. Architecture Anti-Patterns Anonymous functions bound everywhere suck $(document).ready(function(){ ... $('#magic').click(function(e){ $('#yayeffects').slideUp(function(){ ... }); }); $('#happiness').load(url+' #unicorns',function(){ ... }) });
  • 14. Architecture - Object Literal var PI = { onReady : function(){ ... $('#magic').click(PI.candyMtn); $('#happiness').load(url+' #unicorns',PI.unicornCb); }, candyMtn : function(e){ $('#yayeffects').slideUp(PI.slideCb); }, slideCb : function(){ ... }, unicornCb : function(){ ... } } $(document).ready(PI.onReady);
  • 15. Architecture - Object Literal Advantages: Easier to navigate and discuss Profilers give you actual names to work with You can execute these from firebug console You can write unit tests against them
  • 16. Anti-Pattern: The requery // create and append your element $(document.body).append("<div class='baaron'/>"); // requery to bind stuff $("div.baaron").click(function(){}); // better: // swap to appendTo to hold your elem $("<div class='baaron'/>") .appendTo(document.body) .click(function(){});
  • 18. This is not the .context property // find all stylesheets in the body var bodySheets = $('style',document.body); bodySheets.context // ==> BODY element Ignore that for the moment, I know no one that’s found a use
  • 19. $(‘#whats .the’,context) Never pass it a selector string. Ever. No performance gain vs $(root).find(selector) var arms = $('div.robotarm', '#container'); // instead do: var arms = $('#container').find('div.robotarm');
  • 20. $(‘#whats .the’,context) You typically pass it this, but it’s purely a convenience to avoid find() $('form.comments',this).submit(captureSubmit); // exact same as $(this).find('form.comments').submit(captureSubmit); Which is more readable? $('.reply_form', $(this).closest('.comment')).hide(); $(this).closest('.comment').find('.reply_form').hide();
  • 21. The Crowd Say Bo Selector
  • 22. Come on, my selector Selector engines have come a long, long way.
  • 23. Come on, my selector Selector engines have come a long, long way.
  • 24. Come on, my selector Engines work in different ways Top-down, bottom-up, function creation, other crazy shit // from NWMatcher: // selecting '.outmost #outer span' T=e.nodeName;if(T=="SPAN"||T=="span") {while((e=e.parentNode)&&e.nodeType==1) {if((n=e.getAttributeNode("id"))&&n.value=="outer") {if((e=e.parentNode)&&e.nodeType==1) {C=e.className;if(C&&(" "+C+" ").indexOf(" outmost ")>-1) {r[X++]=N;continue main;}}}}}
  • 25. Selector engines, parse direction Left to right (Top-down) Right to left (Bottom-up) Mootools Sizzle Sly YUI 3 Peppy NWMatcher Dojo Acme Ext JS Prototype.js details: http://alexsexton.com/selectors/
  • 26. Selector engines, parse direction div.data table.attendees .gonzalez Left to right (Top-down) Right to left (Bottom-up) Mootools Sizzle Sly YUI 3 Peppy NWMatcher Dojo Acme Ext JS Prototype.js details: http://alexsexton.com/selectors/
  • 27. Selector engines, parse direction Left to right (Top-down) Right to left (Bottom-up) Mootools Sizzle Sly YUI 3 Peppy NWMatcher Dojo Acme Ext JS Prototype.js details: http://alexsexton.com/selectors/
  • 28. Selector engines, parse direction Left to right (Top-down) Right to left (Bottom-up) Mootools Sizzle Sly YUI 3 Peppy NWMatcher Dojo Acme querySelectorAll (qSA) Ext JS Prototype.js details: http://alexsexton.com/selectors/
  • 29. Selector Optimization Specific on the right, light on the left // let's find scott div.data .gonzalez // specific on right, light on the left .data td.gonzalez tag.class if possible on your right-most selector. just tag or just .class on left.
  • 30. Selector Optimization Of course, descending from an #id is best // basic #id-based selector var arms = $('#container div.robotarm'); // hyper-optimized #id case first, then find: var arms = $('#container').find('div.robotarm');
  • 31. Selector Optimization Don’t be needlessly specific // let's find scott .data table.attendees td.gonzalez // better: drop the middle .data td.gonzalez A flatter DOM helps, so move to HTML5 Also a wider range of tags speeds up filters
  • 32. Selector Optimization Avoid the universal selector Avoid the implied universal selector $('.buttons > *') // terribly costly $('.buttons').children() // much better $('.gender :radio') // implied universal $('.gender *:radio') // exact same, explicit now $('.gender input:radio') // much better
  • 33. Selector Optimization Google PageSpeed’s efficient selectors analysis MDC: Writing Efficient CSS https://developer.mozilla.org/en/Writing_Efficient_CSS Benchmark.js http://code.paulirish.com/sandbox/benchmark.js
  • 34. Event Delegation function delegate(type, delegate, handler) { return $(document).bind(type, function(event) { var target = $(event.target); if (target.is(delegate)) { return handler.apply(target, arguments); } }); } delegate('click','td.jehl',createRockstar); // and with live(): $('td.jehl').live('click',createRockstar);
  • 35. Event Delegation live() isn’t just for dynamic content Speeds up page load Only one event handler is bound vs many Good for >3 elements all getting the same handler // using live(), skipping selection on load var jqElem = $(document); jqElem.selector = 'li.ui'; jqElem.live('dblclick', dblhandler);
  • 36. Event Delegation live() isn’t just for dynamic content Speeds up page load Only one event handler is bound vs many Good for >3 elements all getting the same handler // using live(), skipping selection on load var jqElem = $(document); jqElem.selector = 'li.ui'; jqElem.live('dblclick', dblhandler);
  • 37. Event Delegation delegate() bakes in huge performance gains explicit context reduces overhead by ~80% Use it instead of live() if possible // awkward but equivalent $('a.trigger',$('#container')[0]).live('click',handlerFn) // so damn fine $('#container').delegate('click','a.trigger',handlerFn)
  • 38. Event Delegation new in 1.4 .2! delegate() bakes in huge performance gains explicit context reduces overhead by ~80% Use it instead of live() if possible // awkward but equivalent $('a.trigger',$('#container')[0]).live('click',handlerFn) // so damn fine $('#container').delegate('click','a.trigger',handlerFn)
  • 39. The DOM is slow Pull elements off the DOM while you toy with them var table = $('#some-table'); var parent = table.parent(); table.detach(); table.addLotsAndLotsOfRows(); parent.append(table);
  • 40. The DOM is slow Pull elements off the DOM while you toy with them var table = $('#some-table'); var parent = table.parent(); new table.detach(); in 1 .4 table.addLotsAndLotsOfRows(); parent.append(table);
  • 41. Minimize DOM touches Use classes, but if a style change user-selected: jQuery('a.swedberg').css('color', '#BADA55'); jQuery('<style type="text/css"> a.swedberg { color: BADA55; } </style>') .appendTo('head'); Timings for X elements 3000 2250 (1000 iterations) 1500 css() style tag 750 0 1 5 10 20 50
  • 43. Don’t treat jQuery as a Black Box Use the source as your documentation Add this to your bookmark bar, NOW! http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js http://bit.ly/jqsource Determine which are convenience methods: getScript: function( url, callback ) { return jQuery.get(url, null, callback, "script"); }, getJSON: function( url, data, callback ) { return jQuery.get(url, data, callback, "json"); },
  • 44. Don’t treat jQuery as a Black Box Learn the lesser-known methods map(), slice(), stop(), (de)queue(), prevAll(), pushStack(), inArray() , etc // index() in jQuery <= 1.3.2 $('#rdworth').parent().children().index( $('#rdworth')[0] ) // using prevAll() is 10% faster (also sexier) $('#rdworth').prevAll().length // in jQuery 1.4 $('#rdworth').index()
  • 45. Don’t act on absent elements jQuery is very kind and doesn’t throw errors at you Don’t assume it’s just fine to do $('#doesntexist').slideUp() // this will execute genFx(), speed() and animate() // before it hits an each() jQuery UI widgets have a lot of overhead you’ll hit
  • 46. Don’t act on absent elements jQuery.fn.doOnce = function(func){ this.length && func.apply(this); return this; } $('li.cartitems').doOnce(function(){ // make it ajax! o/ });
  • 47. Don’t act on absent elements $.fn.plugin = function(opts){ if(!this.length) return this; var opts = $.extend(...... ... return this.each(...
  • 49. new New Element Creation 1.4 ! in jQuery("<div/>", { id: "foo", rel : "something" css: { height: "50px", width: "50px", color: "blue", backgroundColor: "#ccc" }, click: function() { $(this).css("backgroundColor", "red"); } }).appendTo("body");
  • 50. new eq(), first(), last() 1.4 ! in var lastelem = $elems.eq(-1); // get() too! $('#nav li:first') === $('#nav li').first() $('#nav li:last') === $('#nav li').last()
  • 51. Data() // regular: $(elem).data(key,value); // omg like 10x faster: $.data(elem,key,value);
  • 53. Compression YUI Compressor Sits on Rhino. Comments, whitespace, variable replacement //it already does these micro-optimizations: object['prop'] ==> object.prop {'key':123} ==> {key:123} 'jon's apostophes' ==> "jon's apostrophes" 'bigass ' + 'string' ==> 'bigass string'
  • 54. Variable definition // old 'n busted // new hotness var test1 = 1; var test1 = 1, var test2 = function() { test2 = function() { // function code // function code }; }, var test3 = test2(test1); test3 = test2(test1);
  • 55. Munge the primitives Define shortcuts at the top of your scope Good for both compression and scope chain traversal var TRUE = true, FALSE = false, NULL = null, window = self, undefined = undefined;
  • 56. Munge the primitives Define shortcuts at the top of your scope Good for both compression and scope chain traversal var TRUE = true, FALSE = false, NULL = null, window = self, undefined; undefined = undefined;
  • 57. Munge the primitives (function(){ var window = this, document = document, undefined; /* code */ })(); (function(window, document, undefined){ /* code */ })(this,this.document);
  • 58. var str=‘Let’s put this into action’ // html.no-js html> <!doctype ==> html.js var elem = document.getElementsByTagName('html')[0]; elem.className = elem.className.replace('no-js','js'); <html class="no-js"> // quicker reference, safer replace <head> var elem = document.documentElement; elem.className = elem.className.replace(/bno-jsb/,'js'); <script> // one// change the html class to 'js' line ftw! // in the head, no FOUC document.documentElement.className = document.documentElement.className.replace(/bno-jsb/, </script> 'js'); </body> // shorter with a self-executing anonymous function (function(B){B.className=B.className.replace(/bno-jsb/,
  • 59. var str=‘Let’s put this into action’ // html.no-js ==> html.js var elem = document.getElementsByTagName('html')[0]; elem.className = elem.className.replace('no-js','js'); // quicker reference, safer replace var elem = document.documentElement; elem.className = elem.className.replace(/bno-jsb/,'js'); // one line ftw! document.documentElement.className = document.documentElement.className.replace(/bno-jsb/, 'js'); // shorter with a self-executing anonymous function (function(B){B.className=B.className.replace(/bno-jsb/,
  • 60. // html.no-js ==> html.js var elem = document.getElementsByTagName('html')[0]; var str=‘Let’s put this into action’ elem.className = elem.className.replace('no-js','js'); // quicker reference, safer replace var elem = document.documentElement; elem.className = elem.className.replace(/bno-jsb/,'js'); // one line ftw! document.documentElement.className = document.documentElement.className.replace(/bno-jsb/, 'js'); // shorter with a self-executing anonymous function (function(B){B.className=B.className.replace(/bno-jsb/, 'js')})(document.documentElement); // pass className, object string notation (function(H,C){H[C]=H[C].replace(/bno-jsb/,'js')}) (document.documentElement,'className')
  • 61. Conditionals // old 'n busted if ( type === 'foo' || type === 'bar' ) {} // regex test if ( /^(foo|bar)$/.test(type) ) {} // obj literal lookup (smaller if <5 items) if ( ({foo:1,bar:1})[type] ) {}
  • 62. Logic and Ternary operands // basic function detection document.querySelectorAll && document.querySelectorAll('a:nth-child(2)') // assignment is legal, but it evaluates to the right expression callback && (isCallbackCalled = true) && callback(returnVal); // call or cache the callback function (isCallbackCalled || returnVal) ? fn(returnVal) : (callback = fn); // inline function calls isToday('Saturday') && Math.round(Math.random()) && $('#winnar').show() // if JSON2.js or Native JSON is present, otherwise eval. data = window.JSON && JSON.parse(data) || eval('('+data +')');
  • 63. Write maintainable code As a developer, you should work first and foremost for the user of your products. The second most important person to work for is the developer that takes over from you. - Christian Heilmann
  • 64. Comments /*! * Will not be removed by YUI Compressor */ // for quick toggling on and off: /* */ aaaahYeah(); /* */ /* * / ohHellNo(); /* */
  • 65. Compression Tools CompressorRater http://compressorrater.thruhere.net/ YUI Compressor front-end http://refresh-sf.com/yui/
  • 66. Thanks, ya’ll. Slides at http://paulirish.com/perf @paul_irish thx: Alex Sexton, Ben Alman, Adam Sontag, James Padolsey, temp01, #jquery on Freenode
  • 67. todo shadow effect to code samples more context research and this: http:// groups.google.com/group/jquery-dev/msg/ b4b7935a4013dfe7 and http://ispeakwebstuff.co.uk/ web-design-development-tutorials/clever-jquery- selectors/
  • 68. ` // pngfix for IE6 // e.g. FL.pngfix('img.bigProdShot,a.thumb'); pngfix : function(sel){ // conditional comments for inclusion of that js. if (typeof DD_belatedPNG == 'undefined'){ return; } else { // delay pngfix until window onload $(window).load(function(){ $(sel).each(function() { DD_belatedPNG.fixPng(arguments[1]); }); }); } } // end of FL.pngfix()

Editor's Notes

  1. update the taskspeed shit. delegation facts.
  2. i hang in #jquery so a lot of examples are from real code discussed there.
  3. like copypasting a line or three of code
  4. rebecca murphey will be discussing this technique a lot more
  5. the convenience of context will incur the cost of three extra if() statements in jQuery.fn.init()
  6. selectors. ugh.
  7. did it because i wanted to study. the old ones are probablyw ayyyyy easier to study as the new ones use some crazy techniques
  8. did it because i wanted to study. the old ones are probablyw ayyyyy easier to study as the new ones use some crazy techniques
  9. before sizzle it was LTR. sizzle changed it.
  10. before sizzle it was LTR. sizzle changed it.
  11. before sizzle it was LTR. sizzle changed it.
  12. be brief on the left the more you can filter down the righthandmost expression, the faster it will run.
  13. id is grabbed. optimization
  14. in my testing it didnt speed up basic selecting.
  15. css engine too.
  16. TDs and LI&amp;#x2019;s etccc
  17. document.body as an append target is WIN
  18. padolsey&amp;#x2019;s research on animate()
  19. strings take up a lot of space, so allowing them to be munged helps a lot compress it and look for repetition
  20. DRY obviously
  21. DRY obviously
  22. really understand truthy and falsy ness