diff --git a/tests/Performance/BenchmarkTest.php b/tests/Performance/BenchmarkTest.php
new file mode 100644
index 0000000..3df907e
--- /dev/null
+++ b/tests/Performance/BenchmarkTest.php
@@ -0,0 +1,333 @@
+
+
+
+
+ Hello World
+
+
+
+
+MJML;
+
+ $renderer = new MjmlRenderer();
+ $iterations = 100;
+
+ $startTime = microtime(true);
+ $startMemory = memory_get_usage();
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $renderer->render($mjml);
+ }
+
+ $endTime = microtime(true);
+ $endMemory = memory_get_usage();
+
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+ $memoryUsed = $endMemory - $startMemory;
+
+ // Assert performance is reasonable
+ expect($avgTime)->toBeLessThan(0.1); // Less than 100ms per render
+ expect($memoryUsed)->toBeLessThan(5 * 1024 * 1024); // Less than 5MB total
+
+ echo sprintf(
+ "\nSimple Email: %d iterations in %.4fs (avg: %.4fs, memory: %s)",
+ $iterations,
+ $totalTime,
+ $avgTime,
+ formatBytes($memoryUsed)
+ );
+ });
+
+ it('benchmarks complex email rendering', function () {
+ $mjml = <<<'MJML'
+
+
+
+
+
+
+ Newsletter Title
+
+
+
+
+
+
+
+ Article 1
+ Description text here
+ Read More
+
+
+
+ Article 2
+ Description text here
+ Read More
+
+
+
+
+
+
+ Footer Content
+
+
+
+
+
+
+MJML;
+
+ $renderer = new MjmlRenderer();
+ $iterations = 50;
+
+ $startTime = microtime(true);
+ $startMemory = memory_get_usage();
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $renderer->render($mjml);
+ }
+
+ $endTime = microtime(true);
+ $endMemory = memory_get_usage();
+
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+ $memoryUsed = $endMemory - $startMemory;
+
+ // Assert performance is reasonable for complex emails
+ expect($avgTime)->toBeLessThan(0.2); // Less than 200ms per render
+ expect($memoryUsed)->toBeLessThan(10 * 1024 * 1024); // Less than 10MB total
+
+ echo sprintf(
+ "\nComplex Email: %d iterations in %.4fs (avg: %.4fs, memory: %s)",
+ $iterations,
+ $totalTime,
+ $avgTime,
+ formatBytes($memoryUsed)
+ );
+ });
+
+ it('benchmarks large multi-section email', function () {
+ // Build a large email with many sections
+ $sections = '';
+ for ($i = 0; $i < 10; $i++) {
+ $sections .= <<
+
+
+ Section {$i} Title
+
+
+ This is the content for section {$i}. It contains some text.
+
+
+ Learn More
+
+
+
+SECTION;
+ }
+
+ $mjml = <<
+
+{$sections}
+
+
+MJML;
+
+ $renderer = new MjmlRenderer();
+ $iterations = 25;
+
+ $startTime = microtime(true);
+ $startMemory = memory_get_usage();
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $renderer->render($mjml);
+ }
+
+ $endTime = microtime(true);
+ $endMemory = memory_get_usage();
+
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+ $memoryUsed = $endMemory - $startMemory;
+
+ // Assert performance is reasonable for large emails
+ expect($avgTime)->toBeLessThan(0.5); // Less than 500ms per render
+ expect($memoryUsed)->toBeLessThan(20 * 1024 * 1024); // Less than 20MB total
+
+ echo sprintf(
+ "\nLarge Email (10 sections): %d iterations in %.4fs (avg: %.4fs, memory: %s)",
+ $iterations,
+ $totalTime,
+ $avgTime,
+ formatBytes($memoryUsed)
+ );
+ });
+
+ it('benchmarks parsing performance', function () {
+ $mjml = <<<'MJML'
+
+
+
+
+ Test content
+ Click
+
+
+
+
+
+MJML;
+
+ $iterations = 200;
+
+ $startTime = microtime(true);
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $parser = \MadeByDenis\PhpMjmlRenderer\ParserFactory::create();
+ $parser->parse($mjml);
+ }
+
+ $endTime = microtime(true);
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+
+ // Parser should be fast
+ expect($avgTime)->toBeLessThan(0.01); // Less than 10ms per parse
+
+ echo sprintf(
+ "\nParsing: %d iterations in %.4fs (avg: %.4fs)",
+ $iterations,
+ $totalTime,
+ $avgTime
+ );
+ });
+
+ it('benchmarks hero element rendering', function () {
+ $mjml = <<<'MJML'
+
+
+
+
+ Hero Title
+
+
+ Action
+
+
+
+
+MJML;
+
+ $renderer = new MjmlRenderer();
+ $iterations = 100;
+
+ $startTime = microtime(true);
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $renderer->render($mjml);
+ }
+
+ $endTime = microtime(true);
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+
+ expect($avgTime)->toBeLessThan(0.15); // Less than 150ms per render
+
+ echo sprintf(
+ "\nHero Element: %d iterations in %.4fs (avg: %.4fs)",
+ $iterations,
+ $totalTime,
+ $avgTime
+ );
+ });
+
+ it('benchmarks carousel rendering', function () {
+ $mjml = <<<'MJML'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MJML;
+
+ $renderer = new MjmlRenderer();
+ $iterations = 100;
+
+ $startTime = microtime(true);
+
+ for ($i = 0; $i < $iterations; $i++) {
+ $renderer->render($mjml);
+ }
+
+ $endTime = microtime(true);
+ $totalTime = $endTime - $startTime;
+ $avgTime = $totalTime / $iterations;
+
+ expect($avgTime)->toBeLessThan(0.15); // Less than 150ms per render
+
+ echo sprintf(
+ "\nCarousel (5 images): %d iterations in %.4fs (avg: %.4fs)",
+ $iterations,
+ $totalTime,
+ $avgTime
+ );
+ });
+
+ it('provides performance summary', function () {
+ echo "\n\n=== Performance Benchmark Summary ===\n";
+ echo "All benchmarks completed successfully.\n";
+ echo "Performance metrics are within acceptable thresholds.\n";
+ echo "=====================================\n";
+
+ expect(true)->toBeTrue();
+ });
+});
+
+/**
+ * Format bytes to human-readable format
+ */
+function formatBytes(int $bytes, int $precision = 2): string
+{
+ $units = ['B', 'KB', 'MB', 'GB'];
+ $bytes = max($bytes, 0);
+ $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
+ $pow = min($pow, count($units) - 1);
+ $bytes /= pow(1024, $pow);
+
+ return round($bytes, $precision) . ' ' . $units[$pow];
+}