jquery performance tips eric pascarello askeric@pascarello.com @epascarello presentation files:...

Post on 02-Jan-2016

224 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

jQuery Performance Tips

Eric Pascarello askEric@Pascarello.com

@epascarelloPresentation 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

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

FASTEST

SLOWEST

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

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

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

Additional Context Hints

Syntax:

$( "context selector" )

$( selector, context )

$( context ).find( selector )

Example:

$( "#id div.foo" )

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

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

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

}

}

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 TestMethod Time (ms)

Append each 519Append once 179

Replace wrapped 14

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 TestAttachment Time (ms)Every Cell 519

Table 179

Table contained 500 cells. Tested with Firefox 3.6.13

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

Eric Pascarello askEric@Pascarello.com

@epascarello

top related