Benchmarking & Performance
Relevant source files
The following files were used as context for generating this wiki page:
Cheerio is designed as a "blazingly fast" library for parsing and manipulating HTML and XML by utilizing a simple and consistent DOM model. Unlike full browser-based DOM implementations like JSDOM, Cheerio avoids the overhead of browser inconsistencies and script execution, making its parsing and rendering processes highly efficient.
The project maintains a dedicated benchmarking suite to compare its performance against alternatives and to ensure that performance regressions are not introduced during development. These benchmarks focus on core operations including selection, manipulation, traversal, and attribute management.
Sources: Readme.md:46-48, benchmark/benchmark.ts
Benchmark Architecture
The benchmarking system is built around the tinybench library and compares Cheerio's execution speed against JSDOM. It utilizes a standardized set of HTML documents (primarily jquery.html) to perform various operations.
Execution Flow
The benchmark runner loads a target HTML file, initializes a Cheerio instance, and optionally a JSDOM instance with jQuery injected into its virtual machine context.
The diagram shows the logic for preparing and executing performance comparisons between Cheerio and JSDOM.
Sources: benchmark/benchmark.ts:47-68
Key Components
| Component | Description |
|---|---|
Bench | Instance from tinybench used to track execution metrics. |
benchmark function | An asynchronous wrapper that manages file loading, setup, and execution of test suites. |
SuiteOptions | Interface defining the test logic and an optional setup function for data preparation. |
jQueryScript | A Node.js vm.Script containing jquery.slim.js for execution within JSDOM contexts. |
Sources: benchmark/benchmark.ts:10-45
Performance Optimization Targets
The benchmarking suite focuses on operations that are critical to common scraping and manipulation workflows.
Selection and Traversal
Cheerio measures the speed of selecting elements using standard CSS selectors. Performance is tracked for:
- Global selection (e.g.,
$('*')). - Tag selection (e.g.,
$('li')). - Complex traversals like
.find(),.closest(), and.parentsUntil().
Cheerio implements optimizations to prevent quadratic performance (O(N²)) in selection and mapping operations by utilizing internal Set objects for deduplication.
Sources: benchmark/benchmark.ts:75-81, src/api/traversing.spec.ts:601-633
Manipulation and Memory Management
Manipulation tests include append, prepend, after, and before. Specific "highmem" tests are included for manipulation because JSDOM historically ran out of memory on these operations, whereas Cheerio maintains a lower memory footprint.
This diagram illustrates the comparative testing of DOM manipulation methods that are memory-intensive.
Sources: benchmark/benchmark.ts:86-115
Configuration and Tooling
Benchmarks are executed via a standardized npm script defined in the project configuration.
CLI Options
The benchmark script supports filtering to run specific tests or isolating Cheerio.
--filter <name>: Only runs tests whose name includes the filter string.--cheerio-only: Skips the JSDOM comparison, which is useful for rapid local testing or environments where JSDOM initialization is too slow.
Sources: benchmark/benchmark.ts:16-19, package.json:115
Development Performance Tools
The repository uses several tools that impact development-time performance and code quality:
- Biome: Used for fast linting and formatting.
- Vitest: The primary test runner, chosen for its speed and compatibility.
- Tshy: Used for managing multi-package builds (ESM and CommonJS) efficiently.
Sources: package.json:116-126, biome.json:1-10
Performance Assumptions and Security
Cheerio's performance is partly derived from what it does not do. As defined in the project's threat model, Cheerio does not execute scripts or evaluate expressions found in markup. This lack of a "live" execution environment allows for a simpler, faster internal data structure compared to full browser engines. However, the project recognizes "Resource exhaustion" from legitimate large input as an expected behavior, rather than a vulnerability, noting that parsing very large files (e.g., 500 MB) will naturally consume significant memory.
Sources: THREAT_MODEL.md:12-14, THREAT_MODEL.md:58-60
Summary
Performance is a core pillar of the Cheerio project, validated through automated benchmarks that compare it against JSDOM. By focusing on a lean DOM model and avoiding script execution, Cheerio provides an efficient environment for HTML and XML manipulation. Developers can run these benchmarks using npm run benchmark to verify that performance remains consistent across versions.