300 likes | 460 Views
jQuery Performance Tips. Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB . Quick Overview. Look at common problem areas Selectors Setting Properties Manipulating DOM Figure out the best practice . Selectors . Poorly written selectors will be slow!
E N D
jQuery Performance Tips Eric PascarelloaskEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB
Quick Overview • Look at common problem areas • Selectors • Setting Properties • Manipulating DOM • Figure out the best practice
Selectors Poorly written selectors will be slow! Think of ways to narrow down how much scanning the selector engine has to do
Search Hierarchy FASTEST SLOWEST ID ELEMENT CLASSES ATTRIBUTES DOM CHECKS
Selector Tips Use ids when possible. Do not do element#id Try to use elements with class names Avoid using attributes/partial matches when possible.
Give Selectors Context Better specificity means quicker lookups. $(".foo") »Searches all elements that have class foo! $("div.foo") » Searches all divs that have a class foo $("#bar .foo") » Searches all elementsinside an element $("#bar div.foo") » Searches all divs inside an element
Selector Speed Test Selection made 1000 times with Firefox 3.6.13 on page with 1773 elements
Additional Context Hints Example: $( "#iddiv.foo" ) $( "div.foo", "#id" ) $( "#id").find( "div.foo" ) Syntax: $( "contextselector" ) $( selector, context ) $( context ).find( selector )
Multiple Selectors • Use commas $( "selector1, selector2, selector3" ) • Use add() $( "selector1" ).add( selector2 ).( selector3 ) • Note: selector2/3 can be strings or another jQuery object
Why use multiple selectors? Ctrl V + Ctrl C Happy! $("selector1").click( fncClick );$("selector2").click( fncClick ); $("selector3").click( fncClick ); OR $("selector1, selector2, selector3").click( fncClick );
Is This How You Code? $("#portlet").removeClass("closed"); $("#portlet").addClass("open"); $("#portlet").data("isOpen",true); $("#portlet").find("div.content").slideDown("slow");
Would you do this? ... mycmd.Parameters.Add(Param1) CONN.Open() mycmd.ExecuteNonQuery() CONN.Close() mycmd.Parameters.Add(Param2) CONN.Open() mycmd.ExecuteNonQuery() CONN.Close() mycmd.Parameters.Add(Param3) CONN.Open() mycmd.ExecuteNonQuery() CONN.Close() ...
Cache Your Selectors Set the jQuery object to a variable and reuse it! var portletObj = $("#portlet"); portletObj.removeClass("closed"); portletObj.addClass("open"); portletObj.data("isOpen",true); portletObj.find("div.content").slideDown("slow"); portletObj = null;
Chain Gang Chaining allows for multiple jQuery methods to be joined together. Keeps logical steps together and in order. Drives some developers insane seeing multiple steps on one line!
Chaining Example Set a css class, remove a class, set state data, and animate a child element. $("#portlet").removeClass("closed").addClass("open").data("isOpen",true).find("div.content").slideDown("slow");
Line Breaks For the Queasy $("#portlet") .removeClass("closed") .addClass("open") .data("isOpen",true) .find("div.content") .slideDown("slow");
jQuery’s end() Removes the last filtering state so you have the same context as you did before you filtered. Allows your chains to become even longer!
Lets Add More $("#portlet") .removeClass("closed") .addClass("open") .data("isOpen",true) .find("div.content") //div inside #portlet .slideDown("slow") .end() .find("div.moreMessage") //div inside #portlet .hide();
Caching vs Chaining? Caching and Chaining have no major differences in speed. Chaining ensures that you are caching handlers.
Setting Multiple Attributes var compLogo = $( "#logo" );compLogo.attr("alt","Awesome Corp");compLogo.attr("src","AwesomeCorp.png"); Better var compLogo = $( "#logo" ).attr( { "alt" : "Awesome Corp", "src" : "AwesomeCorp.png" });
Setting Multiple CSS Styles • Use a class when changing multiple styles! $("a.foo").addClass("best"); • Using .css(property,value) or .css({}) causes multiple redraws. • BONUS: can change look and feel without changing JavaScript code!
Be Careful of each() • $(selector).each( function ) can be slow $("a.link").each( function(){ var elem = jQuery(this); var href = elem.attr("href"); if(href.indexOf("https")===0 && href.indexOf("login")>0){ elem.addClass("secure"); } }); • Try a for loop instead var links = $("a.link"); for(var i=links.length-1;i>=0;i--){ var elem = links.eq(i); var href = elem.attr("href"); if(href.indexOf("https")===0 && href.indexOf("login")>0){ elem.addClass("secure"); } }
DOM Manipulation - BAD • Avoid multiple writes to the DOM var ul = $("#myUl"); for(var i=0;i<500;i++){ ul.append("<li>" + i + "</li>"); }
DOM Manipulation - BETTER • Make one write to the DOM var ul = $("#myUl"); var lis = []; for(var i=0;i<500;i++){ lis.push("<li>" + i + "</li>"); } ul.append(lis.join(""));
DOM Manipulation - BEST • Wrap elements in one container element var ulParent = $("#myUl").parent(); var lis = ["<ul>"]; for(var i=0;i<500;i++){ lis.push("<li>" + i + "</li>"); } lis.push("</ul>"); ulParent.html( lis.join("") );
DOM Speed Test Appended 500 lis with Firefox 3.6.13 on page
Event Delegation • Don’t do this $("#myLink").click( function(){ $("#myLink").addClass("red"); } ); • Do this $("#myLink").click( function(){ $(this).addClass("red"); } );
Use Bubbling to your Advantage • This loops through every table cell $("#myTable td").click( function(){ $(this).addClass("selected"); } ); • Same result with one click event $("#myTable").click( function( e ){ var target = e.target; if(target.nodeName.toLowerCase()==="td"){ $(e.target).addClass("selected"); } });
Event Speed Test Table contained 500 cells. Tested with Firefox 3.6.13
Presentation files: http://goo.gl/i6UbB Eric PascarelloaskEric@Pascarello.com @epascarello