From cb2c81b5816f112368c34090f4214bf613c1b881 Mon Sep 17 00:00:00 2001 From: Thomas Tortorini Date: Wed, 16 Mar 2016 19:30:39 +0100 Subject: [PATCH 1/3] optimize-selectors qSA before Sizzle --- page/performance/optimize-selectors.md | 29 +++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/page/performance/optimize-selectors.md b/page/performance/optimize-selectors.md index 44f3b8e6..fa923974 100644 --- a/page/performance/optimize-selectors.md +++ b/page/performance/optimize-selectors.md @@ -21,6 +21,18 @@ $( "#my-table tr:nth-child(odd)" ); Keep in mind that many jQuery extensions, including `:even` in the above example, do not have exact equivalents in the CSS specification. In some situations the convenience of these extensions could outweigh their performance cost. +## Try to segregate the nonstandard parts of your selection + +When you select elements, jQuery will call `querySelectorAll` with your selection. If `querySelectorAll` throws an error, jQuery will refer to its Sizzle engine. So, if you are using at least one of the nonstandard pseudo-classes such as `:contains()`, `:has`, `:even`, `:submit`, etc. You will not take advantage of the native `querySelectorAll`. + +``` +// A long selection with nonstandard pseudo-classes inside +$( "#global.ready .part .list li a:contains('qwerty'):first" ); + +// A long standard selection with a filter outside (faster): +$( "#global.ready .part .list li a").filter( ":contains('qwerty'):first" ); +``` + ## Avoid Excessive Specificity ``` @@ -32,16 +44,15 @@ $( ".data td.gonzalez" ); A "flatter" DOM also helps improve selector performance, as the selector engine has fewer layers to traverse when looking for an element. -## ID-Based Selectors - -Beginning your selector with an ID is a safe bet. +## Save calls to `querySelectorAll` ``` -// Fast: -$( "#container div.robotarm" ); +// If in your HTML there are 2 .container with 5 div in each, +// this line will call querySelectorAll 13 times (1 + 2 + 2*5). +$( ".container" ).children( "div" ).find( ".robotarm" ); -// Super-fast: -$( "#container" ).find( "div.robotarm" ); +// Against only 1 call with this: +$( ".container div .robotarm" ); ``` With the first approach, jQuery queries the DOM using `document.querySelectorAll()`. With the second, jQuery uses `document.getElementById()`, which is faster, although the speed improvement may be diminished by the subsequent call to `.find()`. @@ -51,6 +62,7 @@ With the first approach, jQuery queries the DOM using `document.querySelectorAll When support for older browsers, such as Internet Explorer 8 and below, is necessary, consider the following tips: ### Specificity + Be specific on the right-hand side of your selector, and less specific on the left. ``` @@ -68,9 +80,6 @@ Use `tag.class` if possible on your right-most selector, and just tag or just `. Selections that specify or imply that a match could be found anywhere can be very slow. ``` -$( ".buttons > *" ); // Extremely expensive. -$( ".buttons" ).children(); // Much better. - $( ":radio" ); // Implied universal selection. $( "*:radio" ); // Same thing, explicit now. $( "input:radio" ); // Much better. From c895d3f2709e7e0faab7e186bcba9fe4426fbe27 Mon Sep 17 00:00:00 2001 From: Thomas Tortorini Date: Thu, 17 Mar 2016 16:56:13 +0100 Subject: [PATCH 2/3] remove another old sentence --- page/performance/optimize-selectors.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/page/performance/optimize-selectors.md b/page/performance/optimize-selectors.md index fa923974..c90aa987 100644 --- a/page/performance/optimize-selectors.md +++ b/page/performance/optimize-selectors.md @@ -55,8 +55,6 @@ $( ".container" ).children( "div" ).find( ".robotarm" ); $( ".container div .robotarm" ); ``` -With the first approach, jQuery queries the DOM using `document.querySelectorAll()`. With the second, jQuery uses `document.getElementById()`, which is faster, although the speed improvement may be diminished by the subsequent call to `.find()`. - ## Tips for Older Browsers When support for older browsers, such as Internet Explorer 8 and below, is necessary, consider the following tips: From 1216af95067d410372ea1ee2e2d648b6b4436da9 Mon Sep 17 00:00:00 2001 From: Thomas Tortorini Date: Sat, 19 Mar 2016 15:41:05 +0100 Subject: [PATCH 3/3] A small introduction for + remove a semi colon --- page/performance/optimize-selectors.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/page/performance/optimize-selectors.md b/page/performance/optimize-selectors.md index c90aa987..45304b9e 100644 --- a/page/performance/optimize-selectors.md +++ b/page/performance/optimize-selectors.md @@ -29,7 +29,7 @@ When you select elements, jQuery will call `querySelectorAll` with your selectio // A long selection with nonstandard pseudo-classes inside $( "#global.ready .part .list li a:contains('qwerty'):first" ); -// A long standard selection with a filter outside (faster): +// A long standard selection with a filter outside (faster) $( "#global.ready .part .list li a").filter( ":contains('qwerty'):first" ); ``` @@ -46,6 +46,8 @@ A "flatter" DOM also helps improve selector performance, as the selector engine ## Save calls to `querySelectorAll` +`querySelectorAll` is already really fast, if you want maintain this speed try to call it the least possible. + ``` // If in your HTML there are 2 .container with 5 div in each, // this line will call querySelectorAll 13 times (1 + 2 + 2*5).