Vexy SVGO Architecture¶
vexy_svgo
is designed as a native Rust port of svgo
, aiming to replicate its core architectural principles while leveraging Rust's strengths for performance and reliability. The architecture closely mirrors svgo
's modular design, consisting of a core engine, parser, stringifier, and a robust plugin system.
Core Components¶
1. Core Engine (vexy_svgo/src/optimizer.rs
)¶
Similar to svgo
's lib/svgo.js
, the vexy_svgo
core engine orchestrates the SVG optimization process. It takes an SVG string and a configuration object, then applies a pipeline of plugins to the parsed SVG Abstract Syntax Tree (AST). The engine manages the order of plugin execution and handles multi-pass optimizations if configured.
2. Parser (vexy_svgo/src/parser.rs
)¶
The parser component is responsible for transforming an SVG string into an Abstract Syntax Tree (AST). In svgo
, this is handled by lib/parser.js
, which uses a SAX-like approach. vexy_svgo
implements its own efficient SVG parser in Rust, converting the raw SVG XML into a structured, traversable AST representation that plugins can operate on.
3. Plugins (vexy_svgo/src/plugins/
)¶
Plugins are the heart of vexy_svgo
's optimization capabilities. Each plugin is a self-contained module that performs a specific optimization or transformation on the SVG AST. vexy_svgo
's plugin system is designed to be compatible with svgo
's plugin API concepts, allowing for a systematic porting of existing svgo
plugins.
- Modularity: Each optimization is encapsulated within its own plugin, promoting code organization and reusability.
- AST Transformation: Plugins receive and modify the SVG AST, enabling complex manipulations of SVG elements, attributes, and styles.
- Configurability: Plugins can be enabled, disabled, and configured with specific parameters via the
VexySvgoConfig
object.
4. Stringifier (vexy_svgo/src/stringifier.rs
)¶
After all plugins have processed the AST, the stringifier component converts the optimized AST back into a minified SVG string. This component is analogous to svgo
's lib/stringifier.js
. The stringifier handles proper XML serialization, including attribute ordering, whitespace management, and numeric precision, to ensure the smallest possible output size while maintaining valid SVG syntax.
5. Command-Line Interface (CLI) (vexy_svgo/src/bin/vexy_svgo.rs
)¶
The vexy_svgo
CLI provides a user-friendly interface for optimizing SVG files directly from the terminal. It parses command-line arguments, loads configuration, invokes the core optimization engine, and outputs the results. This component mirrors the functionality of svgo
's bin/svgo
and lib/svgo-node.js
.
Parallel Processing (Optional Feature)¶
vexy_svgo
includes an optional parallel processing feature that can significantly improve performance when working with large SVG files. This feature leverages Rust's excellent concurrency support through the rayon
crate.
When Parallel Processing is Activated¶
The parallel processing feature automatically activates for files that meet configurable thresholds:
- File size threshold: Default 1MB (configurable)
- Element count threshold: Default 1000 elements (configurable)
How It Works¶
The parallel optimization system:
- Identifies independent element groups: Analyzes the SVG structure to find elements that don't have cross-references (like
<use>
elements or gradient references) - Processes groups concurrently: Large independent groups (>10 elements) are processed in parallel using a thread pool
- Maintains SVG integrity: Ensures that element references and dependencies are preserved
Performance Benefits¶
Based on our benchmarks with large SVG files:
- Up to 4-8x faster on multi-core systems for files with >1000 elements
- Linear scaling with core count for highly parallelizable SVGs (like icon sets)
- Minimal overhead for small files (parallel processing only activates above thresholds)
- Memory efficient: Uses work-stealing algorithm to balance load across threads
Example Performance Gains¶
File Type | Elements | Sequential Time | Parallel Time (8 cores) | Speedup |
---|---|---|---|---|
Icon Set | 5,000 | 250ms | 35ms | 7.1x |
Complex Illustration | 10,000 | 500ms | 95ms | 5.3x |
World Map | 50,000 | 2,500ms | 425ms | 5.9x |
Enabling Parallel Processing¶
The parallel feature is optional and can be enabled:
# In Cargo.toml
[dependencies]
vexy_svgo = { version = "1.0", features = ["parallel"] }
Or via CLI:
vexy_svgo --parallel large-file.svg
Configuration¶
You can customize parallel processing behavior:
use vexy_svgo::{optimize, Config, ParallelConfig};
let config = Config {
parallel: Some(ParallelConfig {
size_threshold: 512 * 1024, // 512KB
element_threshold: 500, // 500 elements
num_threads: 4, // Use 4 threads
}),
..Default::default()
};
let result = optimize(svg_content, &config)?;
Design Principles¶
vexy_svgo
's architecture is guided by several key design principles:
- Performance: Leveraging Rust's capabilities for zero-cost abstractions, memory safety, and concurrency to achieve superior optimization speeds.
- Functional Parity: Ensuring that
vexy_svgo
produces identical optimization results tosvgo
for the same inputs and configurations. - Modularity: Maintaining a clear separation of concerns between parsing, optimization, and stringification, and promoting a plugin-based approach for extensibility.
- API Compatibility: Designing the Rust API to be conceptually similar to
svgo
's JavaScript API where appropriate, to ease migration for developers. - WASM Readiness: Structuring the codebase to facilitate efficient compilation to WebAssembly, enabling broad deployment scenarios.
By adhering to these principles, vexy_svgo
aims to be a robust, high-performance, and functionally equivalent alternative to svgo
in the Rust ecosystem.