SlideShare a Scribd company logo
1 of 51
Download to read offline
Recent Changes to
jQuery’s Internals
John Resig

September 12, 2009
No More Browser Sniffing


✤
    As of jQuery 1.3

✤
    jQuery.browser is now deprecated

✤
    All uses of jQuery.browser have been removed from core.

✤
    jQuery.support replaces it.
jQuery.support




✤   div.innerHTML = '   <link/><table></table><a href="/a"
    style="color:red;float:left;opacity:.5;">a
      </a><select><option>text</option></select>';
jQuery.support
    ✤    jQuery.support = {

!   !     // IE strips leading whitespace when .innerHTML is used
!   !     leadingWhitespace: div.firstChild.nodeType == 3,

!   !     // Make sure that tbody elements aren't automatically inserted
!   !     // IE will insert them into empty tables
!   !     tbody: !div.getElementsByTagName("tbody").length,

!   !     // Make sure that link elements get serialized correctly by innerHTML
!   !     // This requires a wrapper element in IE
!   !     htmlSerialize: !!div.getElementsByTagName("link").length,

!   !     // Get the style information from getAttribute
!   !     // (IE uses .cssText insted)
!   !     style: /red/.test( a.getAttribute("style") ),

!   !     // Make sure that URLs aren't manipulated
!   !     // (IE normalizes it by default)
!   !     hrefNormalized: a.getAttribute("href") === "/a",

!   !     // Make sure that element opacity exists
!   !     // (IE uses filter instead)
!   !     opacity: a.style.opacity === "0.5",

!   !     // Verify style float existence
!   !     // (IE uses styleFloat instead of cssFloat)
!   !     cssFloat: !!a.style.cssFloat,

!   !     // Will be defined later
!   !     scriptEval: false,
!   !     noCloneEvent: true,
!   !     boxModel: null
!   };
Modularity
✤   Starting in 1.3.3 code is broken up even more

✤   Core has been split into many sub-modules

    ✤   core.js

    ✤   attributes.js

    ✤   css.js

    ✤   manipulation.js

    ✤   traversing.js
Modularity



✤
    Starting to reduce dependencies in-between files

✤
    Makes it easier to dynamically load portions of the library

✤
    (Mobile jQuery!)
Mobile jQuery?

✤
    “Heavy” core.js

    ✤
        ready event

    ✤
        find() (powered by querySelectorAll)

    ✤
        filter() (very basic functionality)

    ✤
        $.getScript() (for loading modules)

✤
    Still experimenting...
Sizzle
✤
    Standalone selector engine, landed in jQuery 1.3.
                                                    Selector          % Used    # of Uses
✤
    Built for selectors that people actually use.   #id               51.290%   1431
                                                    .class            13.082%   365
                                                    tag               6.416%    179
                                                    tag.class         3.978%    111
                                                    #id tag           2.151%    60
                                                    tag#id            1.935%    54
                                                    #id:visible       1.577%    44
                                                    #id .class        1.434%    40
                                                    .class .class     1.183%    33
                                                    *                 0.968%    27
                                                    #id tag.class     0.932%    26
                                                    #id:hidden        0.789%    22
                                                    tag[name=value]   0.645%    18
                                                    .class tag        0.573%    16
                                                    [name=value]      0.538%    15
                                                    tag tag           0.502%    14
                                                    #id #id           0.430%    12
                                                    #id tag tag       0.358%    10
Right to Left

✤
    Most selector engines (including jQuery, pre-1.3) evaluate a selector
    left to right

✤
    “#id div” - finds the element by ID “id” then finds all divs inside of it.

✤
    Sizzle finds all divs then checks to see if theres an ancestor with an id
    of “id”.

✤
    How CSS engines work in browsers.

✤
    Only one query per selector, rest is filtering.
Reducing Complexity
Analyzing Performance

✤
    Optimizing performance is a huge concern: Faster code = happy
    users!

✤
    Measure execution time

✤
    Loop the code a few times

✤
    Measure the difference:

    ✤
        (new Date).getTime();
Stack Profiling



✤
    jQuery Stack Profiler

✤
    Look for problematic methods and plugins

✤
    http://ejohn.org/blog/deep-profiling-jquery-apps/
Recent Changes to jQuery's Internals
FireUnit



✤
    A simple JavaScript test suite embedded in Firebug.

✤
    http://fireunit.org/
FireUnit Profile Data


                                       {
   fireunit.getProfile();                    "time": 8.443,
                                           "calls": 611,
                                           "data":[
                                           {
                                             "name":"makeArray()",
                                             "calls":1,
                                             "percent":23.58,
                                             "ownTime":1.991,
                                             "time":1.991,
                                             "avgTime":1.991,
                                             "minTime":1.991,
http://ejohn.org/blog/function-call-         "maxTime":1.991,
                                             "fileName":"jquery.js (line 2059)"
             profiling/
Complexity Analysis
 ✤
     Analyze complexity rather than raw time

 ✤
     jQuery Call Count Profiler (uses FireUnit)
                     Method                           Calls           Big-O

.addClass("test");                            542             6n

.addClass("test");                            592             6n

.removeClass("test");                         754             8n

.removeClass("test");                         610             6n

.css("color", "red");                         495             5n

.css({color: "red", border: "1px solid red"}); 887            9n

.remove();                                    23772           2n+n2

.append("<p>test</p>");                       307             3n
Complexity Analysis

✤
    Reducing call count helps to reduce complexity

✤
    Results for 1.3.3:

                   Method                    Calls        Big-O

          .remove();                   298           3n

          .html("<p>test</p>"); 507                  5n

          .empty();                    200           2n


http://ejohn.org/blog/function-call-
ECMAScript 5 Support


✤
    New in 1.3.3

✤
    Removal of arguments.callee

✤
    Switching from ‘RegExp to ‘new RegExp’

✤
    Using JSON.parse, where available.

    ✤
        Support for json2.js is auto-baked in.
Unified Syntax

✤
    Reusable inline functions and RegExp moved outside.
✤
    var rinlinejQuery = / jQueryd+="(?:d+|null)"/g,


!   rleadingWhitespace = /^s+/,
!   rsingleTag = /^<(w+)s*/?>$/,
!   rxhtmlTag = /(<(w+)[^>]*?)/>/g,
!   rselfClosing = /^(?:abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i,
!   rinsideTable = /^<(thead|tbody|tfoot|colg|cap)/,
!   rtbody = /<tbody/i,
!   fcloseTag = function(all, front, tag){
!   ! return rselfClosing.test(tag) ?
!   ! ! all :
!   ! ! front + "></" + tag + ">";
!   };


✤
    http://docs.jquery.com/JQuery_Core_Style_Guidelines
Type Checks


    String: typeof object === "string"
•   Number: typeof object === "number"
•   Boolean: typeof object === "boolean"
•   Object: typeof object === "object"
•   Function: jQuery.isFunction(object)
•   Array: jQuery.isArray(object)
•   Element: object.nodeType
•   null: object === null
•   undefined: typeof variable === "undefined" or object.prop === undefined
•   null or undefined: object == null
isFunction / isArray


✤
    isFunction overhauled in 1.3, isArray added in 1.3.3
✤



    toString = Object.prototype.toString

    isFunction: function( obj ) {


!   ! return toString.call(obj) === "[object Function]";
!   },

!   isArray: function( obj ) {
!   ! return toString.call(obj) === "[object Array]";
!   },
Core
.selector / .context

✤
    Added in 1.3

✤
    Predominantly used for plugins

✤
    var div = jQuery(“div”);
    div.selector === “div”;
    div.context === document;

✤
    jQuery.fn.update = function(){
       return this.pushStack( jQuery(this.selector, this.context), “update” );
    };
jQuery(...) unified


✤
    In 1.3.3

✤
    jQuery(null), jQuery(false), jQuery(undefined) => jQuery([])

✤
    jQuery() is still the same as jQuery(document) (for now)

✤
    BUT jQuery(“div”) points back to a common jQuery(document) root.

✤
    jQuery(“div”).prevObject === jQuery()
jQuery(“TAG”)



✤
    In 1.3.3

✤
    jQuery(“body”) is now a shortcut for jQuery(document.body)

✤
    jQuery(“TAG”) is optimized (skips Sizzle)
Position

✤
    All in 1.3.3

✤
    .get(-N), .eq(-N)
    Access elements/jQuery sets using negative indices.

✤
    .first(), .last()
    Shortcuts for .eq(0) and .eq(-1)

✤
    .toArray()
    Shortcut for .get()
.data()


✤
    In 1.3.3

✤
    Calling .data() (no args) returns the full data object for an element

✤
    jQuery(“#foo”).data(“a”, 1).data(“b”, 2).data() =>
     { a: 1, b: 2 }
Selectors
Document Order
      if ( document.documentElement.compareDocumentPosition ) {
!     sortOrder = function( a, b ) {
!     !    var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
!     !    if ( ret === 0 ) {
!     !    !    hasDuplicate = true;
!     !    }
!     !    return ret;
!     };
}   else if ( "sourceIndex" in document.documentElement ) {
!     sortOrder = function( a, b ) {
!     !    var ret = a.sourceIndex - b.sourceIndex;
!     !    if ( ret === 0 ) {
!     !    !    hasDuplicate = true;
!     !    }
!     !    return ret;
!     };
}   else if ( document.createRange ) {
!     sortOrder = function( a, b ) {
!     !    var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
!     !    aRange.selectNode(a);
!     !    aRange.collapse(true);
!     !    bRange.selectNode(b);
!     !    bRange.collapse(true);
!     !    var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
!     !    if ( ret === 0 ) {
!     !    !    hasDuplicate = true;
!     !    }
!     !    return ret;
!
}
      };      ✤
                 As of 1.3.2 all selectors return in document order
                 (as if you did getElementsByTagName(“*”))
:hidden / :visible

✤
     Changed in 1.3.2, revised in 1.3.3

✤
     Changed logic of :hidden/:visible to use .offsetWidth === 0
     && .offsetHeight === 0 trick
✤    Sizzle.selectors.filters.hidden = function(elem){


!     var width = elem.offsetWidth, height = elem.offsetHeight,
!     !     force = /^tr$/i.test( elem.nodeName ); // ticket #4512
!     return ( width === 0 && height === 0 && !force ) ?
!     !   true :
!     !   !    ( width !== 0 && height !== 0 && !force ) ?
!     !   !    !   false :
!     !   !    !   !   !!( jQuery.curCSS(elem, "display") === "none" );
    };
ID-rooted Queries

✤
    Changed in 1.3.3

✤
    $(“#id div”) sped up dramatically

✤
    #id is detected and used as the root of the query

✤
    $(“div”, “#id”) --> $(“#id”).find(“div”)

✤
    $(“#id div”) can likely never be as fast as $(“#id”).find(“div”)

    ✤
        $(“#id”) is so hyper-optimized, it’s hard to match raw perf.
DOM Manipulation
HTML Fragments

✤
    Overhauled in 1.3

✤
    .append(“<li>foo</li>”) first converts HTML to a DOM fragment

✤
    Fragments act as a loose collection for DOM nodes

✤
    Can be used to insert many nodes with a single operation

✤
    var fragment = document.createDocumentFragment();
    while ( node.firstChild )
      fragment.appendChild( node.firstChild );
    document.body.appendChild( node );
HTML Fragments (redux.)

✤
    In 1.3.3

✤
    It turns out that using fragments makes it really easy to cache them,
    as well.

✤
    Look for common cases that can be cached (simple, small, HTML
    strings that are built more than once).

✤
    Also optimized $(“<some html>”), cut out some unnecessary
    intermediary code.

✤
    jQuery.fragments[“<some html>”] = fragment;
HTML Fragments

✤
    Surprising change:

✤
    for ( var i = 0; i < 250; i++ ) {
      $(“<li>some thing</li>”).attr(“id”, “foo” + i).appendTo(“ul”);
    }

✤
    Now faster than:

✤
    for ( var i = 0; i < 250; i++ ) {
      $(“ul”).append(“<li id=‘foo” + i + “‘>some thing</li>”);
    }
$(“<div/>”)


✤
    In 1.3:

✤
    $(“<div/>”) was made equivalent to $(document.createElement
    (“div”))

✤
    In 1.3.3:

✤
    Logic for handling createElement moved to jQuery() (performance
    improved!)
append(function(){ })
✤
    In 1.3.3 append, prepend, before, after, wrap, wrapAll, replace, replaceAll all
    take a function as an argument

✤
    Compliments .attr(“title”, function(){}) (and CSS)

✤
    Makes:
    $(“li”).each(function(){
        $(this).append(“My id: “ + this.id);
    });

✤
    Also:
    $(“li”).append(function(){
      return “My id: “ + this.id;
    });
.detach()


✤
    In 1.3.3

✤
    Like .remove() but leaves events and data intact.
✤   detach: function( selector ) {


!   !  return this.remove( selector, true );
!   },
DOM Traversal
.closest()


✤
    Added in 1.3

✤
    $(this).closest(“div”) checks if ‘this’ is a div, if not keeps going up the
    tree until it finds the closest one.

✤
    In 1.3.3

✤
    $(this).closest(“.test”, document.body)
    Prevent the traversal from going too far up the tree.
find() perf

✤
    In 1.3.3

✤
    Reduced the number of function calls - Reduced 16 calls per find() to 5.
✤   find: function( selector ) {


!   !    var ret = this.pushStack( "", "find", selector ), length = 0;

!   !    for ( var i = 0, l = this.length; i < l; i++ ) {
!   !    !    length = ret.length;
!   !    !    jQuery.find( selector, this[i], ret );

!   !    !     if ( i > 0 ) {
!   !    !     !    // Make sure that the results are unique
!   !    !     !    for ( var n = length; n < ret.length; n++ ) {
!   !    !     !    !    for ( var r = 0; r < length; r++ ) {
!   !    !     !    !    !    if ( ret[r] === ret[n] ) {
!   !    !     !    !    !    !    ret.splice(n--, 1);
!   !    !     !    !    !    !    break;
!   !    !     !    !    !    }
!   !    !     !    !    }
!   !    !     !    }
!   !    !     }
!   !    }

!   !    return ret;
!   },
find() perf




✤
    Perf for $(“...”) improved, as well (hooked into rootQuery, uses less
    function calls)
.not() / .filter()



✤
    .not(function(){}) (1.3.3)

✤
    .filter(Element), .filter(function(){}) (1.3.3)

✤
    Full API parity inbetween .not() and .filter()
.index()



✤
    In 1.3.3

✤
    $(“div”).index() - position of element relative to siblings

✤
    $(“#foo”).index(“div”) - position relative to all divs
Events
Live Events


✤
    Super-efficient event delegation - uses .closest(), introduced in 1.3.

✤
    1.3.3 adds context and data object support.

✤
    1.3.3 will ship once “submit”, “change”, and “focus/blur” events
    work in .live() (in all browsers).
.bind() `thisObject`


✤
    In 1.3.3

✤
    You can now bind functions enforcing this `this`

✤
    var obj = { method: function(){} };
    $(“div”).bind( “click”, function(){
       this.objProp = true;
    }, obj );
Dynamic Ready Event



✤
    In 1.3.3

✤
    document.readyState is checked to determine if the body is already
    loaded - if so, no need to wait for ready event.
Method                                      Calls      O(N)
.addClass("test");                                                    542             O(6n)

.addClass("test");                                                    592             O(6n)

.removeClass("test");                                                 754             O(8n)

.removeClass("test");                                                 610             O(6n)

.css("color", "red");                                                 495             O(5n)

.css({color: "red", border: "1px solid red"});                        887             O(9n)

.remove();                                                            23772           O(2n+n2)

.append("<p>test</p>");                                               307             O(3n)

.append("<p>test</p><p>test</p><p>test</p><p>test</p><p>test</p>");   319             O(3n)

.show();                                                              394             O(4n)

.hide();                                                              394             O(4n)

.html("<p>test</p>");                                                 28759           O(3n+n2)

.empty();                                                             28452           O(3n+n2)

.is("div");                                                           110

.filter("div");                                                        216             O(2n)

.find("div");                                                          1564            O(16n)
Method                                    Calls      O(N)
.addClass("test");                                                    2

.addClass("test");                                                    2

.removeClass("test");                                                 2

.removeClass("test");                                                 2

.css("color", "red");                                                 102

.css({color: "red", border: "1px solid red"});                        201           O(2n)

.remove();                                                            299           O(3n)

.append("<p>test</p>");                                               116

.append("<p>test</p><p>test</p><p>test</p><p>test</p><p>test</p>");   128

.show();                                                              394           O(4n)

.hide();                                                              394           O(4n)

.html("<p>test</p>");                                                 100

.empty();                                                             201           O(2n)

.is("div");                                                           109

.filter("div");                                                        216           O(2n)

.find("div");                                                          495           O(5n)
Recent Changes to jQuery's Internals

More Related Content

What's hot

Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutesSimon Willison
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An AnalysisJustin Finkelstein
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
DOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkDOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkMatthew McCullough
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMJonathan Wage
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperJonathan Wage
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMJonathan Wage
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-onAndrea Valenza
 

What's hot (17)

Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An Analysis
 
Django - sql alchemy - jquery
Django - sql alchemy - jqueryDjango - sql alchemy - jquery
Django - sql alchemy - jquery
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
I regret nothing
I regret nothingI regret nothing
I regret nothing
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
DOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript FrameworkDOSUG Intro to JQuery JavaScript Framework
DOSUG Intro to JQuery JavaScript Framework
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
jQuery
jQueryjQuery
jQuery
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
Daily notes
Daily notesDaily notes
Daily notes
 

Similar to Recent Changes to jQuery's Internals

[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularErik Guzman
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и DjangoMoscowDjango
 
jQuery Rescue Adventure
jQuery Rescue AdventurejQuery Rescue Adventure
jQuery Rescue AdventureAllegient
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1DjangoCon2008
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance DjangoDjangoCon2008
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to ProtractorJie-Wei Wu
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Eric Palakovich Carr
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passageErik Rose
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
PHP security audits
PHP security auditsPHP security audits
PHP security auditsDamien Seguy
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaoladrewz lin
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
J Query The Write Less Do More Javascript Library
J Query   The Write Less Do More Javascript LibraryJ Query   The Write Less Do More Javascript Library
J Query The Write Less Do More Javascript Libraryrsnarayanan
 

Similar to Recent Changes to jQuery's Internals (20)

Jquery
JqueryJquery
Jquery
 
J query
J queryJ query
J query
 
Jquery fundamentals
Jquery fundamentalsJquery fundamentals
Jquery fundamentals
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & Angular
 
Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
jQuery Rescue Adventure
jQuery Rescue AdventurejQuery Rescue Adventure
jQuery Rescue Adventure
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance Django
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
Introduction to Protractor
Introduction to ProtractorIntroduction to Protractor
Introduction to Protractor
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Django’s nasal passage
Django’s nasal passageDjango’s nasal passage
Django’s nasal passage
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaola
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
J Query The Write Less Do More Javascript Library
J Query   The Write Less Do More Javascript LibraryJ Query   The Write Less Do More Javascript Library
J Query The Write Less Do More Javascript Library
 

More from jeresig

Does Coding Every Day Matter?
Does Coding Every Day Matter?Does Coding Every Day Matter?
Does Coding Every Day Matter?jeresig
 
Accidentally Becoming a Digital Librarian
Accidentally Becoming a Digital LibrarianAccidentally Becoming a Digital Librarian
Accidentally Becoming a Digital Librarianjeresig
 
2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)jeresig
 
Computer Vision as Art Historical Investigation
Computer Vision as Art Historical InvestigationComputer Vision as Art Historical Investigation
Computer Vision as Art Historical Investigationjeresig
 
Hacking Art History
Hacking Art HistoryHacking Art History
Hacking Art Historyjeresig
 
Using JS to teach JS at Khan Academy
Using JS to teach JS at Khan AcademyUsing JS to teach JS at Khan Academy
Using JS to teach JS at Khan Academyjeresig
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art Historyjeresig
 
NYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri ResultsNYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri Resultsjeresig
 
EmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image AnalysisEmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image Analysisjeresig
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art Historyjeresig
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)jeresig
 
Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)jeresig
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jeresig
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jeresig
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jeresig
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobilejeresig
 
jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)jeresig
 
Holistic JavaScript Performance
Holistic JavaScript PerformanceHolistic JavaScript Performance
Holistic JavaScript Performancejeresig
 
New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)jeresig
 
Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)jeresig
 

More from jeresig (20)

Does Coding Every Day Matter?
Does Coding Every Day Matter?Does Coding Every Day Matter?
Does Coding Every Day Matter?
 
Accidentally Becoming a Digital Librarian
Accidentally Becoming a Digital LibrarianAccidentally Becoming a Digital Librarian
Accidentally Becoming a Digital Librarian
 
2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)2014: John's Favorite Thing (Neo4j)
2014: John's Favorite Thing (Neo4j)
 
Computer Vision as Art Historical Investigation
Computer Vision as Art Historical InvestigationComputer Vision as Art Historical Investigation
Computer Vision as Art Historical Investigation
 
Hacking Art History
Hacking Art HistoryHacking Art History
Hacking Art History
 
Using JS to teach JS at Khan Academy
Using JS to teach JS at Khan AcademyUsing JS to teach JS at Khan Academy
Using JS to teach JS at Khan Academy
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
NYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri ResultsNYARC 2014: Frick/Zeri Results
NYARC 2014: Frick/Zeri Results
 
EmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image AnalysisEmpireJS: Hacking Art with Node js and Image Analysis
EmpireJS: Hacking Art with Node js and Image Analysis
 
Applying Computer Vision to Art History
Applying Computer Vision to Art HistoryApplying Computer Vision to Art History
Applying Computer Vision to Art History
 
JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)JavaScript Libraries (Ajax Exp 2006)
JavaScript Libraries (Ajax Exp 2006)
 
Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)Introduction to jQuery (Ajax Exp 2006)
Introduction to jQuery (Ajax Exp 2006)
 
jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)jQuery Recommendations to the W3C (2011)
jQuery Recommendations to the W3C (2011)
 
jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)jQuery Open Source Process (RIT 2011)
jQuery Open Source Process (RIT 2011)
 
jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)jQuery Open Source Process (Knight Foundation 2011)
jQuery Open Source Process (Knight Foundation 2011)
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobile
 
jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)jQuery Open Source (Fronteer 2011)
jQuery Open Source (Fronteer 2011)
 
Holistic JavaScript Performance
Holistic JavaScript PerformanceHolistic JavaScript Performance
Holistic JavaScript Performance
 
New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)New Features Coming in Browsers (RIT '09)
New Features Coming in Browsers (RIT '09)
 
Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)Introduction to jQuery (Ajax Exp 2007)
Introduction to jQuery (Ajax Exp 2007)
 

Recently uploaded

UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 

Recently uploaded (20)

UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 

Recent Changes to jQuery's Internals

  • 1. Recent Changes to jQuery’s Internals John Resig September 12, 2009
  • 2. No More Browser Sniffing ✤ As of jQuery 1.3 ✤ jQuery.browser is now deprecated ✤ All uses of jQuery.browser have been removed from core. ✤ jQuery.support replaces it.
  • 3. jQuery.support ✤ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a </a><select><option>text</option></select>';
  • 4. jQuery.support ✤ jQuery.support = { ! ! // IE strips leading whitespace when .innerHTML is used ! ! leadingWhitespace: div.firstChild.nodeType == 3, ! ! // Make sure that tbody elements aren't automatically inserted ! ! // IE will insert them into empty tables ! ! tbody: !div.getElementsByTagName("tbody").length, ! ! // Make sure that link elements get serialized correctly by innerHTML ! ! // This requires a wrapper element in IE ! ! htmlSerialize: !!div.getElementsByTagName("link").length, ! ! // Get the style information from getAttribute ! ! // (IE uses .cssText insted) ! ! style: /red/.test( a.getAttribute("style") ), ! ! // Make sure that URLs aren't manipulated ! ! // (IE normalizes it by default) ! ! hrefNormalized: a.getAttribute("href") === "/a", ! ! // Make sure that element opacity exists ! ! // (IE uses filter instead) ! ! opacity: a.style.opacity === "0.5", ! ! // Verify style float existence ! ! // (IE uses styleFloat instead of cssFloat) ! ! cssFloat: !!a.style.cssFloat, ! ! // Will be defined later ! ! scriptEval: false, ! ! noCloneEvent: true, ! ! boxModel: null ! };
  • 5. Modularity ✤ Starting in 1.3.3 code is broken up even more ✤ Core has been split into many sub-modules ✤ core.js ✤ attributes.js ✤ css.js ✤ manipulation.js ✤ traversing.js
  • 6. Modularity ✤ Starting to reduce dependencies in-between files ✤ Makes it easier to dynamically load portions of the library ✤ (Mobile jQuery!)
  • 7. Mobile jQuery? ✤ “Heavy” core.js ✤ ready event ✤ find() (powered by querySelectorAll) ✤ filter() (very basic functionality) ✤ $.getScript() (for loading modules) ✤ Still experimenting...
  • 8. Sizzle ✤ Standalone selector engine, landed in jQuery 1.3. Selector % Used # of Uses ✤ Built for selectors that people actually use. #id 51.290% 1431 .class 13.082% 365 tag 6.416% 179 tag.class 3.978% 111 #id tag 2.151% 60 tag#id 1.935% 54 #id:visible 1.577% 44 #id .class 1.434% 40 .class .class 1.183% 33 * 0.968% 27 #id tag.class 0.932% 26 #id:hidden 0.789% 22 tag[name=value] 0.645% 18 .class tag 0.573% 16 [name=value] 0.538% 15 tag tag 0.502% 14 #id #id 0.430% 12 #id tag tag 0.358% 10
  • 9. Right to Left ✤ Most selector engines (including jQuery, pre-1.3) evaluate a selector left to right ✤ “#id div” - finds the element by ID “id” then finds all divs inside of it. ✤ Sizzle finds all divs then checks to see if theres an ancestor with an id of “id”. ✤ How CSS engines work in browsers. ✤ Only one query per selector, rest is filtering.
  • 11. Analyzing Performance ✤ Optimizing performance is a huge concern: Faster code = happy users! ✤ Measure execution time ✤ Loop the code a few times ✤ Measure the difference: ✤ (new Date).getTime();
  • 12. Stack Profiling ✤ jQuery Stack Profiler ✤ Look for problematic methods and plugins ✤ http://ejohn.org/blog/deep-profiling-jquery-apps/
  • 14. FireUnit ✤ A simple JavaScript test suite embedded in Firebug. ✤ http://fireunit.org/
  • 15. FireUnit Profile Data { fireunit.getProfile(); "time": 8.443, "calls": 611, "data":[ { "name":"makeArray()", "calls":1, "percent":23.58, "ownTime":1.991, "time":1.991, "avgTime":1.991, "minTime":1.991, http://ejohn.org/blog/function-call- "maxTime":1.991, "fileName":"jquery.js (line 2059)" profiling/
  • 16. Complexity Analysis ✤ Analyze complexity rather than raw time ✤ jQuery Call Count Profiler (uses FireUnit) Method Calls Big-O .addClass("test"); 542 6n .addClass("test"); 592 6n .removeClass("test"); 754 8n .removeClass("test"); 610 6n .css("color", "red"); 495 5n .css({color: "red", border: "1px solid red"}); 887 9n .remove(); 23772 2n+n2 .append("<p>test</p>"); 307 3n
  • 17. Complexity Analysis ✤ Reducing call count helps to reduce complexity ✤ Results for 1.3.3: Method Calls Big-O .remove(); 298 3n .html("<p>test</p>"); 507 5n .empty(); 200 2n http://ejohn.org/blog/function-call-
  • 18. ECMAScript 5 Support ✤ New in 1.3.3 ✤ Removal of arguments.callee ✤ Switching from ‘RegExp to ‘new RegExp’ ✤ Using JSON.parse, where available. ✤ Support for json2.js is auto-baked in.
  • 19. Unified Syntax ✤ Reusable inline functions and RegExp moved outside. ✤ var rinlinejQuery = / jQueryd+="(?:d+|null)"/g, ! rleadingWhitespace = /^s+/, ! rsingleTag = /^<(w+)s*/?>$/, ! rxhtmlTag = /(<(w+)[^>]*?)/>/g, ! rselfClosing = /^(?:abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i, ! rinsideTable = /^<(thead|tbody|tfoot|colg|cap)/, ! rtbody = /<tbody/i, ! fcloseTag = function(all, front, tag){ ! ! return rselfClosing.test(tag) ? ! ! ! all : ! ! ! front + "></" + tag + ">"; ! }; ✤ http://docs.jquery.com/JQuery_Core_Style_Guidelines
  • 20. Type Checks String: typeof object === "string" • Number: typeof object === "number" • Boolean: typeof object === "boolean" • Object: typeof object === "object" • Function: jQuery.isFunction(object) • Array: jQuery.isArray(object) • Element: object.nodeType • null: object === null • undefined: typeof variable === "undefined" or object.prop === undefined • null or undefined: object == null
  • 21. isFunction / isArray ✤ isFunction overhauled in 1.3, isArray added in 1.3.3 ✤ toString = Object.prototype.toString isFunction: function( obj ) { ! ! return toString.call(obj) === "[object Function]"; ! }, ! isArray: function( obj ) { ! ! return toString.call(obj) === "[object Array]"; ! },
  • 22. Core
  • 23. .selector / .context ✤ Added in 1.3 ✤ Predominantly used for plugins ✤ var div = jQuery(“div”); div.selector === “div”; div.context === document; ✤ jQuery.fn.update = function(){ return this.pushStack( jQuery(this.selector, this.context), “update” ); };
  • 24. jQuery(...) unified ✤ In 1.3.3 ✤ jQuery(null), jQuery(false), jQuery(undefined) => jQuery([]) ✤ jQuery() is still the same as jQuery(document) (for now) ✤ BUT jQuery(“div”) points back to a common jQuery(document) root. ✤ jQuery(“div”).prevObject === jQuery()
  • 25. jQuery(“TAG”) ✤ In 1.3.3 ✤ jQuery(“body”) is now a shortcut for jQuery(document.body) ✤ jQuery(“TAG”) is optimized (skips Sizzle)
  • 26. Position ✤ All in 1.3.3 ✤ .get(-N), .eq(-N) Access elements/jQuery sets using negative indices. ✤ .first(), .last() Shortcuts for .eq(0) and .eq(-1) ✤ .toArray() Shortcut for .get()
  • 27. .data() ✤ In 1.3.3 ✤ Calling .data() (no args) returns the full data object for an element ✤ jQuery(“#foo”).data(“a”, 1).data(“b”, 2).data() => { a: 1, b: 2 }
  • 29. Document Order if ( document.documentElement.compareDocumentPosition ) { ! sortOrder = function( a, b ) { ! ! var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; ! ! if ( ret === 0 ) { ! ! ! hasDuplicate = true; ! ! } ! ! return ret; ! }; } else if ( "sourceIndex" in document.documentElement ) { ! sortOrder = function( a, b ) { ! ! var ret = a.sourceIndex - b.sourceIndex; ! ! if ( ret === 0 ) { ! ! ! hasDuplicate = true; ! ! } ! ! return ret; ! }; } else if ( document.createRange ) { ! sortOrder = function( a, b ) { ! ! var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); ! ! aRange.selectNode(a); ! ! aRange.collapse(true); ! ! bRange.selectNode(b); ! ! bRange.collapse(true); ! ! var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); ! ! if ( ret === 0 ) { ! ! ! hasDuplicate = true; ! ! } ! ! return ret; ! } }; ✤ As of 1.3.2 all selectors return in document order (as if you did getElementsByTagName(“*”))
  • 30. :hidden / :visible ✤ Changed in 1.3.2, revised in 1.3.3 ✤ Changed logic of :hidden/:visible to use .offsetWidth === 0 && .offsetHeight === 0 trick ✤ Sizzle.selectors.filters.hidden = function(elem){ ! var width = elem.offsetWidth, height = elem.offsetHeight, ! ! force = /^tr$/i.test( elem.nodeName ); // ticket #4512 ! return ( width === 0 && height === 0 && !force ) ? ! ! true : ! ! ! ( width !== 0 && height !== 0 && !force ) ? ! ! ! ! false : ! ! ! ! ! !!( jQuery.curCSS(elem, "display") === "none" ); };
  • 31. ID-rooted Queries ✤ Changed in 1.3.3 ✤ $(“#id div”) sped up dramatically ✤ #id is detected and used as the root of the query ✤ $(“div”, “#id”) --> $(“#id”).find(“div”) ✤ $(“#id div”) can likely never be as fast as $(“#id”).find(“div”) ✤ $(“#id”) is so hyper-optimized, it’s hard to match raw perf.
  • 33. HTML Fragments ✤ Overhauled in 1.3 ✤ .append(“<li>foo</li>”) first converts HTML to a DOM fragment ✤ Fragments act as a loose collection for DOM nodes ✤ Can be used to insert many nodes with a single operation ✤ var fragment = document.createDocumentFragment(); while ( node.firstChild ) fragment.appendChild( node.firstChild ); document.body.appendChild( node );
  • 34. HTML Fragments (redux.) ✤ In 1.3.3 ✤ It turns out that using fragments makes it really easy to cache them, as well. ✤ Look for common cases that can be cached (simple, small, HTML strings that are built more than once). ✤ Also optimized $(“<some html>”), cut out some unnecessary intermediary code. ✤ jQuery.fragments[“<some html>”] = fragment;
  • 35. HTML Fragments ✤ Surprising change: ✤ for ( var i = 0; i < 250; i++ ) { $(“<li>some thing</li>”).attr(“id”, “foo” + i).appendTo(“ul”); } ✤ Now faster than: ✤ for ( var i = 0; i < 250; i++ ) { $(“ul”).append(“<li id=‘foo” + i + “‘>some thing</li>”); }
  • 36. $(“<div/>”) ✤ In 1.3: ✤ $(“<div/>”) was made equivalent to $(document.createElement (“div”)) ✤ In 1.3.3: ✤ Logic for handling createElement moved to jQuery() (performance improved!)
  • 37. append(function(){ }) ✤ In 1.3.3 append, prepend, before, after, wrap, wrapAll, replace, replaceAll all take a function as an argument ✤ Compliments .attr(“title”, function(){}) (and CSS) ✤ Makes: $(“li”).each(function(){ $(this).append(“My id: “ + this.id); }); ✤ Also: $(“li”).append(function(){ return “My id: “ + this.id; });
  • 38. .detach() ✤ In 1.3.3 ✤ Like .remove() but leaves events and data intact. ✤ detach: function( selector ) { ! ! return this.remove( selector, true ); ! },
  • 40. .closest() ✤ Added in 1.3 ✤ $(this).closest(“div”) checks if ‘this’ is a div, if not keeps going up the tree until it finds the closest one. ✤ In 1.3.3 ✤ $(this).closest(“.test”, document.body) Prevent the traversal from going too far up the tree.
  • 41. find() perf ✤ In 1.3.3 ✤ Reduced the number of function calls - Reduced 16 calls per find() to 5. ✤ find: function( selector ) { ! ! var ret = this.pushStack( "", "find", selector ), length = 0; ! ! for ( var i = 0, l = this.length; i < l; i++ ) { ! ! ! length = ret.length; ! ! ! jQuery.find( selector, this[i], ret ); ! ! ! if ( i > 0 ) { ! ! ! ! // Make sure that the results are unique ! ! ! ! for ( var n = length; n < ret.length; n++ ) { ! ! ! ! ! for ( var r = 0; r < length; r++ ) { ! ! ! ! ! ! if ( ret[r] === ret[n] ) { ! ! ! ! ! ! ! ret.splice(n--, 1); ! ! ! ! ! ! ! break; ! ! ! ! ! ! } ! ! ! ! ! } ! ! ! ! } ! ! ! } ! ! } ! ! return ret; ! },
  • 42. find() perf ✤ Perf for $(“...”) improved, as well (hooked into rootQuery, uses less function calls)
  • 43. .not() / .filter() ✤ .not(function(){}) (1.3.3) ✤ .filter(Element), .filter(function(){}) (1.3.3) ✤ Full API parity inbetween .not() and .filter()
  • 44. .index() ✤ In 1.3.3 ✤ $(“div”).index() - position of element relative to siblings ✤ $(“#foo”).index(“div”) - position relative to all divs
  • 46. Live Events ✤ Super-efficient event delegation - uses .closest(), introduced in 1.3. ✤ 1.3.3 adds context and data object support. ✤ 1.3.3 will ship once “submit”, “change”, and “focus/blur” events work in .live() (in all browsers).
  • 47. .bind() `thisObject` ✤ In 1.3.3 ✤ You can now bind functions enforcing this `this` ✤ var obj = { method: function(){} }; $(“div”).bind( “click”, function(){ this.objProp = true; }, obj );
  • 48. Dynamic Ready Event ✤ In 1.3.3 ✤ document.readyState is checked to determine if the body is already loaded - if so, no need to wait for ready event.
  • 49. Method Calls O(N) .addClass("test"); 542 O(6n) .addClass("test"); 592 O(6n) .removeClass("test"); 754 O(8n) .removeClass("test"); 610 O(6n) .css("color", "red"); 495 O(5n) .css({color: "red", border: "1px solid red"}); 887 O(9n) .remove(); 23772 O(2n+n2) .append("<p>test</p>"); 307 O(3n) .append("<p>test</p><p>test</p><p>test</p><p>test</p><p>test</p>"); 319 O(3n) .show(); 394 O(4n) .hide(); 394 O(4n) .html("<p>test</p>"); 28759 O(3n+n2) .empty(); 28452 O(3n+n2) .is("div"); 110 .filter("div"); 216 O(2n) .find("div"); 1564 O(16n)
  • 50. Method Calls O(N) .addClass("test"); 2 .addClass("test"); 2 .removeClass("test"); 2 .removeClass("test"); 2 .css("color", "red"); 102 .css({color: "red", border: "1px solid red"}); 201 O(2n) .remove(); 299 O(3n) .append("<p>test</p>"); 116 .append("<p>test</p><p>test</p><p>test</p><p>test</p><p>test</p>"); 128 .show(); 394 O(4n) .hide(); 394 O(4n) .html("<p>test</p>"); 100 .empty(); 201 O(2n) .is("div"); 109 .filter("div"); 216 O(2n) .find("div"); 495 O(5n)