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

วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูล
วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูลวิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูล
วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูลCoco Tan
 
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4พงศธร ภักดี
 
"Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์
 "Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์ "Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์
"Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์noodeejideenoodeejid
 
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...Dr.Kridsanapong Lertbumroongchai
 
ใบงานที่ 1.1 เรื่อง ประเภทแหล่งข้อมูล
ใบงานที่  1.1  เรื่อง ประเภทแหล่งข้อมูลใบงานที่  1.1  เรื่อง ประเภทแหล่งข้อมูล
ใบงานที่ 1.1 เรื่อง ประเภทแหล่งข้อมูลThanawut Rattanadon
 
ตัวอย่างข้อตกลงการปฏิบัติราชการ
ตัวอย่างข้อตกลงการปฏิบัติราชการตัวอย่างข้อตกลงการปฏิบัติราชการ
ตัวอย่างข้อตกลงการปฏิบัติราชการอลงกรณ์ อารามกูล
 
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษ
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษงานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษ
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษNontaporn Pilawut
 
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้Chay Kung
 
ตัวอย่างแผนธุรกิจPocket tissue
ตัวอย่างแผนธุรกิจPocket tissueตัวอย่างแผนธุรกิจPocket tissue
ตัวอย่างแผนธุรกิจPocket tissueNattakorn Sunkdon
 
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560ประพันธ์ เวารัมย์
 
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555RMUTT
 
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์Mjjeje Mint
 
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"บทความเรื่อง "การเรียนรู้ตลอดชีวิต"
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"Mahidol University, Thailand
 
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...อบต. เหล่าโพนค้อ
 
ผังงาน Flowchart
ผังงาน Flowchartผังงาน Flowchart
ผังงาน FlowchartRatchakorn Ice
 
กำหนดการโครงการต่าง ๆ
กำหนดการโครงการต่าง ๆกำหนดการโครงการต่าง ๆ
กำหนดการโครงการต่าง ๆLooktan Kp
 

What's hot (20)

วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูล
วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูลวิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูล
วิทยาการคำนวณ ม.5 - บทที่ 2 การเก็บรวบรวมและสำรวจข้อมูล
 
แนวทางสอบสัมภาษณ์
แนวทางสอบสัมภาษณ์แนวทางสอบสัมภาษณ์
แนวทางสอบสัมภาษณ์
 
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4
แผนการสอน โปรแกรมคอมพิวเตอร์กราฟิก ม.4
 
"Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์
 "Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์ "Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์
"Loadแนวข้อสอบ เจ้าหน้าที่บริหารงานทั่วไป มหาวิทยาลัยธรรมศาสตร์
 
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...
การออกแบบเรซูเม่และแฟ้มสะสมผลงานในยุคดิจิทัล (Resume and Portfolio Design in ...
 
ใบงานที่ 1.1 เรื่อง ประเภทแหล่งข้อมูล
ใบงานที่  1.1  เรื่อง ประเภทแหล่งข้อมูลใบงานที่  1.1  เรื่อง ประเภทแหล่งข้อมูล
ใบงานที่ 1.1 เรื่อง ประเภทแหล่งข้อมูล
 
ตัวอย่างข้อตกลงการปฏิบัติราชการ
ตัวอย่างข้อตกลงการปฏิบัติราชการตัวอย่างข้อตกลงการปฏิบัติราชการ
ตัวอย่างข้อตกลงการปฏิบัติราชการ
 
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษ
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษงานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษ
งานวิจัย ภาษาอังกฤษ การเทียบเสียงอักษร ไทย-อังกฤษ
 
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้
เอกสารประกอบหลักสูตร การผลิตหนังสั้นเพื่อการเรียนรู้
 
ตัวอย่างแผนธุรกิจPocket tissue
ตัวอย่างแผนธุรกิจPocket tissueตัวอย่างแผนธุรกิจPocket tissue
ตัวอย่างแผนธุรกิจPocket tissue
 
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560
ระเบียบกระทรวงการคลังว่าด้วยการจัดซื้อจัดจ้าง พ.ศ. 2560
 
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555
รายงานการประชุมหัวหน้าแผนกครั้งที่ 2 2555
 
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์
ความรู้เบื้องต้นเกี่ยวกับสื่อสิ่งพิมพ์
 
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"บทความเรื่อง "การเรียนรู้ตลอดชีวิต"
บทความเรื่อง "การเรียนรู้ตลอดชีวิต"
 
ความรู้เกี่ยวกับนโยบายและแผน
ความรู้เกี่ยวกับนโยบายและแผนความรู้เกี่ยวกับนโยบายและแผน
ความรู้เกี่ยวกับนโยบายและแผน
 
Chapt3
Chapt3Chapt3
Chapt3
 
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...
งานนำเสนอวิสัยทัศน์ในการปฏิบัติราชการเพื่อแต่งตั้งเป็นปลัดองค์การบริหารส่วนตำ...
 
ผังงาน Flowchart
ผังงาน Flowchartผังงาน Flowchart
ผังงาน Flowchart
 
กำหนดการโครงการต่าง ๆ
กำหนดการโครงการต่าง ๆกำหนดการโครงการต่าง ๆ
กำหนดการโครงการต่าง ๆ
 
แบบฝึกหัดที่ 3 Microsoft PowerPoint
แบบฝึกหัดที่ 3 Microsoft PowerPointแบบฝึกหัดที่ 3 Microsoft PowerPoint
แบบฝึกหัดที่ 3 Microsoft PowerPoint
 

Viewers also liked

jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)Addy Osmani
 
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
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutesSimon Willison
 
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)

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

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
 

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

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

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 

Recently uploaded (20)

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 

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