jQuery Performance Rules

1,733 views

Published on

Rules that would help you in writing jQuery code in efficient manner, which will result in better performance of your web application/site

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,733
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
48
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

jQuery Performance Rules

  1. 1. jQuery Performance Rules I hear...I forget I see...and I remember I do...and I understand - Ancient Chinese Proverb
  2. 2. No best practices Browser has to do more work Impacts performance – CPU utilization
  3. 3. 1. Always Descend From an #id <ul><li><div id=&quot;content&quot;> </li></ul><ul><ul><li><form method=&quot;post&quot; action=&quot;/&quot;> </li></ul></ul><ul><ul><ul><li><h2>Traffic Light</h2> </li></ul></ul></ul><ul><ul><ul><li><ul id=&quot;traffic_light&quot;> </li></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;on&quot; name=&quot;light&quot; value=&quot;red&quot; /> Red</li> </li></ul></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;off&quot; name=&quot;light&quot; value=&quot;yellow&quot; /> Yellow</li> </li></ul></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;off&quot; name=&quot;light&quot; value=&quot;green&quot; /> Green</li> </li></ul></ul></ul></ul><ul><ul><ul><li></ul> </li></ul></ul></ul><ul><ul><ul><li><input class=&quot;button&quot; id=&quot;traffic_button&quot; type=&quot;submit&quot; value=&quot;Go&quot; /> </li></ul></ul></ul><ul><ul><li></form> </li></ul></ul><ul><li></div> </li></ul>Selecting the button like this is slower: var traffic_button = $('#content .button'); Instead, select the button directly: var traffic_button = $('#traffic_button'); When selecting multiple elements, always descend from the closest parent ID. var traffic_lights = $('#traffic_light input');
  4. 4. 2. Use Tags Before Classes <ul><li><div id=&quot;content&quot;> </li></ul><ul><ul><li><form method=&quot;post&quot; action=&quot;/&quot;> </li></ul></ul><ul><ul><ul><li><h2>Traffic Light</h2> </li></ul></ul></ul><ul><ul><ul><li><ul id=&quot;traffic_light&quot;> </li></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;on&quot; name=&quot;light&quot; value=&quot;red&quot; /> Red</li> </li></ul></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;off&quot; name=&quot;light&quot; value=&quot;yellow&quot; /> Yellow</li> </li></ul></ul></ul></ul><ul><ul><ul><ul><li><li><input type=&quot;radio&quot; class=&quot;off&quot; name=&quot;light&quot; value=&quot;green&quot; /> Green</li> </li></ul></ul></ul></ul><ul><ul><ul><li></ul> </li></ul></ul></ul><ul><ul><ul><li><input class=&quot;button&quot; id=&quot;traffic_button&quot; type=&quot;submit&quot; value=&quot;Go&quot; /> </li></ul></ul></ul><ul><ul><li></form> </li></ul></ul><ul><li></div> </li></ul>Always prefix a class with a tag name (and remember to descend from an ID): var active_light = $('#traffic_light input.on');
  5. 5. 3. Cache jQuery Objects <ul><li>Cache jQuery objects to a variable, never repeat a jQuery selection in your application. </li></ul><ul><li>For example, never do this… </li></ul><ul><li>$('#traffic_light input.on).bind('click', function(){...}); </li></ul><ul><li>$('#traffic_light input.on).css('border', '3px dashed yellow'); </li></ul><ul><li>$('#traffic_light input.on).css('background-color', 'orange'); </li></ul><ul><li>$('#traffic_light input.on).fadeIn('slow'); </li></ul><ul><li>Instead, first save the object to a local variable, and continue your operations: </li></ul><ul><li>var $active_light = $('#traffic_light input.on'); </li></ul><ul><li>$active_light.bind('click', function(){...}); </li></ul><ul><li>$active_light.css('border', '3px dashed yellow'); </li></ul><ul><li>$active_light.css('background-color', 'orange'); </li></ul><ul><li>$active_light.fadeIn('slow'); </li></ul><ul><li>Storing jQuery results for later </li></ul><ul><li>$my = { </li></ul><ul><li>head : $('head'), </li></ul><ul><li>traffic_light : $('#traffic_light'), </li></ul><ul><li>traffic_button : $('#traffic_button') </li></ul><ul><li> }; </li></ul>
  6. 6. 4. Harness the Power of Chaining <ul><li>This allows us to write less code, making our JavaScript more lightweight. </li></ul><ul><li>var $active_light = $('#traffic_light input.on'); </li></ul><ul><li>$active_light.bind('click', function(){...}) </li></ul><ul><li>.css('border', '3px dashed yellow') </li></ul><ul><li>.css('background-color', 'orange') </li></ul><ul><li>.fadeIn('slow'); </li></ul>
  7. 7. 5. Use Sub-queries <ul><li>jQuery allows us to run additional selector operations on a wrapped set. This reduces performance overhead on subsequent selections since we already grabbed and stored the parent object in a local variable. </li></ul><ul><li>var $traffic_light = $('#traffic_light'), </li></ul><ul><li>$active_light = $traffic_light.find('input.on'), </li></ul><ul><li>$inactive_lights = $traffic_light.find('input.off'); </li></ul><ul><li>Tip: You can declare multiple local variables by separating them with commas – save those bytes! </li></ul>
  8. 8. 6. Limit Direct DOM Manipulation <ul><li>The basic idea here is to create exactly what you need in memory, and then update the DOM. This is not a jQuery best practice, but a must for efficient JavaScript. </li></ul><ul><li>For example, if you need to dynamically create a list of elements, do not do this: </li></ul><ul><li>var top_100_list = [...], // assume this has 100 unique strings </li></ul><ul><li>$mylist = $('#mylist'); // jQuery selects our <ul> element </li></ul><ul><li>for (var i=0, l=top_100_list.length; i<l; i++) </li></ul><ul><li>{ </li></ul><ul><li> $mylist.append('<li>' + top_100_list[i] + '</li>'); </li></ul><ul><li>} </li></ul><ul><li>Instead, we want to create the entire set of elements in a string before inserting into the DOM: </li></ul><ul><li>var top_100_list = [...], // assume this has 100 unique strings </li></ul><ul><li>$mylist = $('#mylist'), // jQuery selects our <ul> element </li></ul><ul><li>top_100_li = &quot;&quot;; // This will store our list items </li></ul><ul><li>for (var i=0, l=top_100_list.length; i<l; i++) </li></ul><ul><li>{ </li></ul><ul><li> top_100_li += '<li>' + top_100_list[i] + '</li>'; </li></ul><ul><li>} </li></ul><ul><li> $mylist.html(top_100_li); </li></ul>
  9. 9. 7. Leverage Event Delegation (a.k.a. Bubbling) <ul><li>Every event (e.g. click, mouseover, etc.) in JavaScript “bubbles” up the DOM tree to parent elements. This is incredibly useful when we want many elements (nodes) to call the same function. </li></ul><ul><li>A binding like this is inefficient. </li></ul><ul><li>$('#entryform input).bind('focus', function(){ </li></ul><ul><li>$(this).addClass('selected'); </li></ul><ul><li>}).bind('blur', function(){ </li></ul><ul><li>$(this).removeClass('selected'); </li></ul><ul><li>}); </li></ul><ul><li>Instead, we should listen for the focus and blur events at the parent level. </li></ul><ul><li>$('#entryform).bind('focus', function(e){ </li></ul><ul><li>var cell = $(e.target); // e.target grabs the node that triggered the event. cell.addClass('selected'); </li></ul><ul><li>}).bind('blur', function(e){ </li></ul><ul><li>var cell = $(e.target); </li></ul><ul><li>cell.removeClass('selected'); </li></ul><ul><li>}); </li></ul><ul><li>The parent node acts as a dispatcher and can then do work based on what target element triggered the event. </li></ul>
  10. 10. 8. Eliminate Query Waste <ul><li>Although jQuery fails nicely if it does not find any matching elements, it still takes time to look for them. If you have one global JavaScript for your entire site, it may be tempting to throw every one of your jQuery functions into </li></ul><ul><li>$(document).ready(function(){ // all my glorious code }) </li></ul><ul><li>Your Global JS library would look something like this: </li></ul><ul><li>var mylib = { </li></ul><ul><li>article_page : </li></ul><ul><li>{ </li></ul><ul><li>init : function() </li></ul><ul><li>{ </li></ul><ul><li>// Article page specific jQuery functions. </li></ul><ul><li>} </li></ul><ul><li>}, </li></ul><ul><li>traffic_light : </li></ul><ul><li>{ </li></ul><ul><li>init : function() </li></ul><ul><li>{ </li></ul><ul><li>// Traffic light specific jQuery functions. </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li> } </li></ul>
  11. 11. 9. Defer to $(window).load <ul><li>Although $(document).ready is incredibly useful, it occurs during page render while objects are still downloading. If you notice your page stalling while loading, all those $(document).ready functions could be the reason why. </li></ul><ul><li>You can reduce CPU utilization during the page load by binding your jQuery functions to the $(window).load event, which occurs after all objects called by the HTML (including <iframe> content) have downloaded. </li></ul><ul><li>$(window).load(function(){ // jQuery functions to initialize after the page has loaded. }); </li></ul><ul><li>Superfluous functionality such as drag and drop, binding visual effects and animations, pre-fetching hidden images, etc., are all good candidates for this technique. </li></ul>
  12. 12. Recap <ul><li>Always Descend From an #id </li></ul><ul><li>Use Tags Before Classes </li></ul><ul><li>Cache jQuery Objects </li></ul><ul><li>Harness the Power of Chaining </li></ul><ul><li>Use Sub-queries </li></ul><ul><li>Limit Direct DOM Manipulation </li></ul><ul><li>Leverage Event Delegation (a.k.a. Bubbling) </li></ul><ul><li>Eliminate Query Waste </li></ul><ul><li>Defer to $(window).load </li></ul>

×