30
jQuery Performance Tips Eric Pascarello [email protected] @epascarello Presentation files: goo.gl/i6UbB

JQuery Performance Tips Eric Pascarello [email protected] @epascarello Presentation files: goo.gl/i6UbB

Embed Size (px)

Citation preview

Page 1: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

jQuery Performance Tips

Eric Pascarello [email protected]

@epascarelloPresentation files: goo.gl/i6UbB

Page 2: 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

Page 3: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Selectors

• Poorly written selectors will be slow!• Think of ways to narrow down how much

scanning the selector engine has to do

Page 4: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Search Hierarchy

1. ID2. ELEMENT3. CLASSES4. ATTRIBUTES5. DOM CHECKS

FASTEST

SLOWEST

Page 5: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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.

Page 6: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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 elements inside an element

• $("#bar div.foo") » Searches all divs inside an element

Page 7: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Selector Speed TestSelector Time (ms)#myH2 10

h2 11.myH2 369

h2.myH2 372#myH2.myH2 387

h2#myH2 364h2#myH2.myH2 375

Selection made 1000 times with Firefox 3.6.13 on page with 1773 elements

Page 8: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Additional Context Hints

Syntax:

$( "context selector" )

$( selector, context )

$( context ).find( selector )

Example:

$( "#id div.foo" )

$( "div.foo", "#id" )

$( "#id").find( "div.foo" )

Page 9: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Multiple Selectors

• Use commas$( "selector1, selector2, selector3" )

• Use add()$( "selector1" ).add( selector2 ).( selector3 )– Note: selector2/3 can be strings or another jQuery object

Page 10: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Why use multiple selectors?

Ctrl V + Ctrl C Happy!$("selector1").click( fncClick );$("selector2").click( fncClick ); $("selector3").click( fncClick );

OR

$("selector1, selector2, selector3").click( fncClick );

Page 11: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Is This How You Code?

$("#portlet").removeClass("closed");

$("#portlet").addClass("open");

$("#portlet").data("isOpen",true);

$("#portlet").find("div.content").slideDown("slow");

Page 12: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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()

...

Page 13: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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;

Page 14: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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!

Page 15: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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");

Page 16: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Line Breaks For the Queasy

$("#portlet")

.removeClass("closed")

.addClass("open")

.data("isOpen",true)

.find("div.content")

.slideDown("slow");

Page 17: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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!

Page 18: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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();

Page 19: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Caching vs Chaining?

• Caching and Chaining have no major differences in speed.

• Chaining ensures that you are caching handlers.

Page 20: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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"  });

Page 21: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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!

Page 22: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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 insteadvar 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");

}

}

Page 23: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

DOM Manipulation - BAD

• Avoid multiple writes to the DOM

var ul = $("#myUl");

for(var i=0;i<500;i++){

ul.append("<li>" + i + "</li>");

}

Page 24: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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(""));

Page 25: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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("") );

Page 26: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

DOM Speed TestMethod Time (ms)

Append each 519Append once 179

Replace wrapped 14

Appended 500 lis with Firefox 3.6.13 on page

Page 27: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Event Delegation

• Don’t do this$("#myLink").click( function(){

$("#myLink").addClass("red");

} );

• Do this$("#myLink").click( function(){

$(this).addClass("red");

} );

Page 28: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

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");

}

});

Page 29: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Event Speed TestAttachment Time (ms)Every Cell 519

Table 179

Table contained 500 cells. Tested with Firefox 3.6.13

Page 30: JQuery Performance Tips Eric Pascarello askEric@Pascarello.com @epascarello Presentation files: goo.gl/i6UbB

Presentation files: http://goo.gl/i6UbB

Eric Pascarello [email protected]

@epascarello