recent changes to jquery's internals
DESCRIPTION
A run-down of all the features and internal changes made in 1.3, 1.3.1, 1.3.2, and 1.3.3/1.4.TRANSCRIPT
![Page 1: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/1.jpg)
September 12, 2009
Recent Changes tojQuery’s InternalsJohn Resig
![Page 2: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/2.jpg)
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.
![Page 3: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/3.jpg)
jQuery.support
✤ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a </a><select><option>text</option></select>';
![Page 4: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/4.jpg)
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! };
![Page 5: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/5.jpg)
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
![Page 6: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/6.jpg)
Modularity
✤ Starting to reduce dependencies in-between files
✤ Makes it easier to dynamically load portions of the library
✤ (Mobile jQuery!)
![Page 7: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/7.jpg)
Mobile jQuery?
✤ “Heavy” core.js
✤ ready event
✤ find() (powered by querySelectorAll)
✤ filter() (very basic functionality)
✤ $.getScript() (for loading modules)
✤ Still experimenting...
![Page 8: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/8.jpg)
Sizzle
✤ Standalone selector engine, landed in jQuery 1.3.
✤ Built for selectors that people actually use.Selector % Used # of Uses#id 51.290% 1431.class 13.082% 365tag 6.416% 179tag.class 3.978% 111#id tag 2.151% 60tag#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% 22tag[name=value] 0.645% 18.class tag 0.573% 16[name=value] 0.538% 15tag tag 0.502% 14#id #id 0.430% 12#id tag tag 0.358% 10
![Page 9: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/9.jpg)
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.
![Page 10: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/10.jpg)
Reducing Complexity
![Page 11: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/11.jpg)
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();
![Page 12: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/12.jpg)
Stack Profiling
✤ jQuery Stack Profiler
✤ Look for problematic methods and plugins
✤ http://ejohn.org/blog/deep-profiling-jquery-apps/
![Page 13: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/13.jpg)
![Page 14: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/14.jpg)
FireUnit
✤ A simple JavaScript test suite embedded in Firebug.
✤ http://fireunit.org/
![Page 15: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/15.jpg)
FireUnit Profile Data
{ "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, "maxTime":1.991, "fileName":"jquery.js (line 2059)" }, // etc.]}
fireunit.getProfile();
http://ejohn.org/blog/function-call-profiling/
![Page 16: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/16.jpg)
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
![Page 17: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/17.jpg)
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-profiling/
![Page 18: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/18.jpg)
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.
![Page 19: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/19.jpg)
Unified Syntax
✤ Reusable inline functions and RegExp moved outside.
✤ var rinlinejQuery = / jQuery\d+="(?:\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
![Page 20: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/20.jpg)
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
![Page 21: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/21.jpg)
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]";! },
![Page 22: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/22.jpg)
Core
![Page 23: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/23.jpg)
.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” );};
![Page 24: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/24.jpg)
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()
![Page 25: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/25.jpg)
jQuery(“TAG”)
✤ In 1.3.3
✤ jQuery(“body”) is now a shortcut for jQuery(document.body)
✤ jQuery(“TAG”) is optimized (skips Sizzle)
![Page 26: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/26.jpg)
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()
![Page 27: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/27.jpg)
.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 }
![Page 28: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/28.jpg)
Selectors
![Page 29: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/29.jpg)
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(“*”))
![Page 30: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/30.jpg)
: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" ); };
![Page 31: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/31.jpg)
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.
![Page 32: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/32.jpg)
DOM Manipulation
![Page 33: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/33.jpg)
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 );
![Page 34: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/34.jpg)
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;
![Page 35: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/35.jpg)
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>”);}
![Page 36: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/36.jpg)
$(“<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!)
![Page 37: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/37.jpg)
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;});
![Page 38: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/38.jpg)
.detach()
✤ In 1.3.3
✤ Like .remove() but leaves events and data intact.
✤ detach: function( selector ) {
! ! return this.remove( selector, true );! },
![Page 39: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/39.jpg)
DOM Traversal
![Page 40: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/40.jpg)
.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.
![Page 41: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/41.jpg)
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;! },
![Page 42: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/42.jpg)
find() perf
✤ Perf for $(“...”) improved, as well (hooked into rootQuery, uses less function calls)
![Page 43: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/43.jpg)
.not() / .filter()
✤ .not(function(){}) (1.3.3)
✤ .filter(Element), .filter(function(){}) (1.3.3)
✤ Full API parity inbetween .not() and .filter()
![Page 44: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/44.jpg)
.index()
✤ In 1.3.3
✤ $(“div”).index() - position of element relative to siblings
✤ $(“#foo”).index(“div”) - position relative to all divs
![Page 45: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/45.jpg)
Events
![Page 46: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/46.jpg)
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).
![Page 47: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/47.jpg)
.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 );
![Page 48: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/48.jpg)
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.
![Page 49: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/49.jpg)
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)
![Page 50: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/50.jpg)
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)
![Page 51: Recent Changes to jQuery's Internals](https://reader031.vdocument.in/reader031/viewer/2022020206/546a4900b4af9f6b2c8b45c3/html5/thumbnails/51.jpg)