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

Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery PresentationRod Johnson
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQueryGunjan Kumar
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQueryUnobtrusive javascript with jQuery
Unobtrusive javascript with jQueryAngel Ruiz
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creationbenalman
 
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJRealize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJLeonardo Balter
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design PatternsRobert Casanova
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutesSimon Willison
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do MoreRemy Sharp
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 

What's hot (20)

Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
jQuery Presentation
jQuery PresentationjQuery Presentation
jQuery Presentation
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Unobtrusive javascript with jQuery
Unobtrusive javascript with jQueryUnobtrusive javascript with jQuery
Unobtrusive javascript with jQuery
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
 
Jquery
JqueryJquery
Jquery
 
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJRealize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
 
FuncUnit
FuncUnitFuncUnit
FuncUnit
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
前端概述
前端概述前端概述
前端概述
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
jQuery
jQueryjQuery
jQuery
 

Viewers also liked

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 CodeRebecca Murphey
 
EPAM. Hadoop MR streaming in Hive
EPAM. Hadoop MR streaming in HiveEPAM. Hadoop MR streaming in Hive
EPAM. Hadoop MR streaming in HiveEugene Yushin
 
Finite State Machines and C++
Finite State Machines and C++Finite State Machines and C++
Finite State Machines and C++Klika Tech, Inc
 
Writing Scalable React Applications: Introduction
Writing Scalable React Applications: IntroductionWriting Scalable React Applications: Introduction
Writing Scalable React Applications: IntroductionKlika Tech, Inc
 
How to Write UI Automated Tests
How to Write UI Automated TestsHow to Write UI Automated Tests
How to Write UI Automated TestsKlika Tech, Inc
 
Organization of Automated Testing
Organization of Automated TestingOrganization of Automated Testing
Organization of Automated TestingKlika Tech, Inc
 
CAP theorem and distributed systems
CAP theorem and distributed systemsCAP theorem and distributed systems
CAP theorem and distributed systemsKlika Tech, Inc
 
[Tech Talks] Typesafe Stack Introduction
[Tech Talks] Typesafe Stack Introduction[Tech Talks] Typesafe Stack Introduction
[Tech Talks] Typesafe Stack IntroductionKlika Tech, Inc
 
An Overview of HTML5 Storage
An Overview of HTML5 StorageAn Overview of HTML5 Storage
An Overview of HTML5 StoragePaul Irish
 
Introduction to Serverless
Introduction to ServerlessIntroduction to Serverless
Introduction to ServerlessNikolaus Graf
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksAddy Osmani
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript PerformanceThomas Fuchs
 
Trabalho sobre Queimaduras
Trabalho sobre QueimadurasTrabalho sobre Queimaduras
Trabalho sobre QueimadurasRui Alves
 
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 AnythingNGINX, Inc.
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
Docker for Java Developers
Docker for Java DevelopersDocker for Java Developers
Docker for Java DevelopersNGINX, Inc.
 
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 awesomeAndrew Hull
 

Viewers also liked (20)

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
 
jQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & Tricks
 
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
 
Telenor Connexion
Telenor Connexion Telenor Connexion
Telenor Connexion
 

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 Practicesbrinsknaps
 
Cheap frontend tricks
Cheap frontend tricksCheap frontend tricks
Cheap frontend tricksambiescent
 
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 Knowgirish82
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterpriseDave Artz
 
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 Secretssmueller_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 bigAndy Peterson
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin Cataldo
 
Beyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance JavascriptBeyond DOMReady: Ultra High-Performance Javascript
Beyond DOMReady: Ultra High-Performance Javascriptaglemann
 
DOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryDOM Scripting Toolkit - jQuery
DOM Scripting Toolkit - jQueryRemy Sharp
 
Ember background basics
Ember background basicsEmber background basics
Ember background basicsPhilipp Fehre
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of DjangoJacob Kaplan-Moss
 
jQuery Foot-Gun Features
jQuery Foot-Gun FeaturesjQuery Foot-Gun Features
jQuery Foot-Gun Featuresdmethvin
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery ApplicationsRebecca Murphey
 

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
 
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
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 

More from Paul Irish

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 enhancementPaul Irish
 
webfonts & @font-face :: in brief
webfonts & @font-face :: in briefwebfonts & @font-face :: in brief
webfonts & @font-face :: in briefPaul Irish
 
Progressive Advancement in Web8
Progressive Advancement in Web8Progressive Advancement in Web8
Progressive Advancement in Web8Paul Irish
 
Squeezing The Best Out Of Webfonts
Squeezing The Best Out Of WebfontsSqueezing The Best Out Of Webfonts
Squeezing The Best Out Of WebfontsPaul Irish
 
Modernizr - Detecting HTML5 and CSS3 support
Modernizr - Detecting HTML5 and CSS3 supportModernizr - Detecting HTML5 and CSS3 support
Modernizr - Detecting HTML5 and CSS3 supportPaul Irish
 
Employing Custom Fonts
Employing Custom FontsEmploying Custom Fonts
Employing Custom FontsPaul Irish
 
Practical Design Solutions from Japan
Practical Design Solutions from JapanPractical Design Solutions from Japan
Practical Design Solutions from JapanPaul Irish
 
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 2009Paul Irish
 

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

Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 

Recently uploaded (20)

Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 

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