Uncovering the Secrets of Sizzle.js: Why It Was the Fastest DOM Selector
This article dissects the Sizzle.js source code, explaining its high performance, design choices such as native API usage, right‑to‑left parsing, tokenization, and modular analysis, while showing how studying its architecture can inform modern frontend framework development.
Introduction
jQuery once dominated front‑end development with its Sizzle selector engine, touted as the fastest DOM selector of its time. Analyzing Sizzle’s source reveals design tricks that remain valuable for understanding modern MVVM frameworks and for building efficient custom modules.
Key Features of Sizzle
High efficiency achieved through extensive use of native browser APIs.
Support for a wide range of selectors (ID, class, tag, hierarchical, pseudo‑classes).
Compact size – the compressed library is only about 3 KB.
How to Approach Framework Source Code
When tackling a large codebase like Sizzle (over 2,000 lines), adopt a two‑step strategy:
Simplify the module hierarchy – isolate the core logic and remove compatibility layers.
Reconstruct the author’s design intent – use comments and documentation to map out the architecture before diving into details.
Design Strategies Behind Sizzle’s Speed
Sizzle gains performance from several angles:
Prefer native browser APIs (e.g.,
getElementById,
querySelectorAll) whenever possible, falling back to custom logic only for older browsers.
Limit the search space by narrowing the root node and creating a seed set of candidate elements.
Parse selectors from right to left, which reduces the number of DOM traversals because each child has only one parent.
Compile frequently used selectors into reusable filter functions, trading space for time.
Left‑to‑Right vs. Right‑to‑Left Evaluation
Consider the selector
#div[name=wrapper] div[name=ad2]. A left‑to‑right approach would first locate all
divelements, then test each for the required attributes, leading to many unnecessary checks. The right‑to‑left method starts with the most specific part (
div[name=ad2]), then moves up the DOM tree, dramatically reducing the search space.
Tokenization (Lexical Analysis)
Sizzle converts a selector string into a token array using a
tokenizefunction. Each token has the form
{type: 'TOKEN_TYPE', value: 'matched string', matches: regexResult}. Types include
ID,
CLASS,
TAG,
ATTR,
CHILD, and
PSEUDO.
Example: the selector
#div_test spanyields the token array
[{type:'ID',value:'div_test'},{type:'TAG',value:'span'}]. When multiple selectors are separated by commas, Sizzle creates a two‑dimensional
groupsarray, each sub‑array representing one selector sequence.
The tokenization loop performs the following steps:
Remove leading commas.
Push combinators (
>,
+,
~, whitespace) into the token array.
Match and push ID, TAG, CLASS, ATTR, CHILD, and PSEUDO tokens, applying any necessary pre‑processing.
Continue until the selector string is exhausted.
Selector Filtering
After tokenization, Sizzle iterates over
Expr.filterto apply the appropriate matching logic for each token type (ID, CLASS, TAG, ATTR, CHILD, PSEUDO). This modular filter design enables fast, reusable checks during the selection process.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.