Skip to content

Performance: HTML Compression

To ensure your application is as fast as possible, PhpSPA includes a powerful, built-in HTML compressor. It automatically minifies your final HTML output by removing whitespace, comments, and other unnecessary characters, which reduces the page size and leads to faster load times. ⚡

Auto-Detection

By default, PhpSPA tries to auto-detect the best settings. However, you can take full control for fine-tuned performance.

Automatic Compression (Default Behavior)

PhpSPA automatically initializes the HTML compressor when you create your App instance. The second parameter controls this behavior and is set to true by default.

<?php
use PhpSPA\App;

// Auto-initialization is enabled by default
$app = new App($layout);

// This is the same as:
$app = new App($layout, true);

Smart Detection

When auto-initialization is enabled, PhpSPA automatically detects the best compression level based on your server environment. You don't need to manually configure anything!

Disabling Auto-Initialization

If you want full manual control over compression, you can disable auto-initialization:

<?php
use PhpSPA\App;

// Disable auto-initialization
$app = new App($layout, false);

// Now you must manually configure compression if you want it
$app->compression(Compressor::LEVEL_AGGRESSIVE, true);

When to Disable

Disable auto-initialization only if you need precise control over compression settings for specific use cases.

The easiest way to manage compression is to set the application's environment. PhpSPA will then apply a sensible preset for you.

Compression is disabled to make debugging easier.

<?php
use PhpSPA\Compression\Compressor;

$app->compressionEnvironment(Compressor::ENV_DEVELOPMENT);

A high level of compression is enabled for maximum performance.

<?php
use PhpSPA\Compression\Compressor;

$app->compressionEnvironment(Compressor::ENV_PRODUCTION);

Environment Presets

Set the environment to automatically configure compression with sensible defaults.

Manual Compression Control

For more granular control, you can manually set the compression level and enable or disable Gzip.

<?php
use PhpSPA\App;
use PhpSPA\Compression\Compressor;

$app = new App($layout);

// Manually set the highest level of compression and enable Gzip
$app->compression(Compressor::LEVEL_EXTREME, true);

Compression Levels

There are several levels available, from basic to extreme:

  • Compressor::LEVEL_NONE: No compression is applied
  • Compressor::LEVEL_BASIC: Removes comments and basic whitespace
  • Compressor::LEVEL_AGGRESSIVE: Performs more intense whitespace removal
  • Compressor::LEVEL_EXTREME: Applies the most aggressive minification for the smallest possible file size

Asset Caching Behavior

Smart Caching with Auto-Invalidation

When compression is enabled (any level above LEVEL_NONE), PhpSPA caches compressed assets to .generated.php files for faster subsequent requests. The cache automatically invalidates when source files change!

How Asset Caching Works

When you enable compression, PhpSPA generates cached files alongside your component files:

examples/components/
├── Counter.php
└── generated/
    ├── a3f8b2c1d5e9f7a4b2c8d1e6f9a3b7c2.generated.php       # Cached compressed JS
    └── d4e7a1b8c5f2e9d6a3b7c1f4e8a2d5b9.generated.php       # Cached compressed CSS

Smart Cache Invalidation

Cache filenames are MD5 hashes of the original filename and file modification time. When a source file changes, its modification time updates, generating a new hash and automatically creating a fresh cache file.

Custom Cache Location

You can customize where cache files are stored using setGeneratedCacheDirectory(). See Asset Caching: Custom Cache Directory for details.

Smart Cache Invalidation: PhpSPA automatically detects when source files change by using file modification timestamps. When a file changes:

  1. The file's modification time updates
  2. A new cache hash is generated (based on filename + modification time)
  3. The new cache file is created with fresh compressed content
  4. Old cache files naturally expire (can be cleaned up periodically)

This means:

  • Production: Excellent performance - compressed content is reused when unchanged
  • Development: Always fresh - file changes automatically generate new cache files
  • No manual tracking: File system timestamps handle everything automatically

Use environment-based configuration to automatically handle caching:

<?php
use PhpSPA\App;

// Read from environment variable
$app = new App($layout);
$app->compressionEnvironment($_ENV['APP_ENV']);

Then configure your .env file:

APP_ENV=development
  • Compression disabled (LEVEL_NONE)
  • No cached files generated
  • Changes appear immediately (no compression overhead)
  • Existing cached files automatically deleted when switching to development
APP_ENV=production
  • Maximum compression (LEVEL_EXTREME)
  • Assets cached for performance
  • Blazing fast subsequent requests
  • Generated files reused until source changes detected

Environment Switching

When you switch from production back to development mode (LEVEL_NONE), PhpSPA automatically deletes cached .generated.php files to prevent stale content issues.

Manual Cache Management

The cache is automatically managed, but you can manually clear it if needed:

# Delete all generated cache files
find . -name "*.generated.php" -type f -delete

# Or clean up a specific directory
rm -rf /path/to/cache/directory/*.generated.php

Or temporarily disable compression to bypass the cache entirely:

<?php
// Force fresh assets without caching
$app->compression(Compressor::LEVEL_NONE);

Automatic Cache Invalidation

PhpSPA uses file modification timestamps to automatically invalidate cache. When you edit a source file, a new cache file is generated on the next request. Old cache files can be periodically cleaned up, but they won't be served since the hash no longer matches.

IIFE Wrapping for Component Scripts

PhpSPA automatically wraps component JavaScript in Immediately Invoked Function Expressions (IIFE) for scope isolation:

  • Component JS: Always wrapped in IIFE (()=>{/* your code */})()
  • Global JS: Never wrapped to prevent duplicate execution and to allow global functions to be reused
  • External script links: Never wrapped (assumed pre-bundled)

This ensures: - Component scripts don't pollute the global scope - Variables and functions are properly isolated - Global scripts are not wrapped to allow other scripts (global and components) to reuse variables, functions and classes.


⚙️ Native Compressor Configuration

New in v2.0.9

Three new methods give you full control over the native compressor and esbuild behavior.


🚀 JavaScript Minification with esbuild

Starting from v2.0.9, PhpSPA uses the professional esbuild bundler by default for JavaScript minification. Esbuild provides superior minification, bundling, and tree-shaking compared to the built-in C++/PHP minifier.

Installing esbuild

For best performance, install esbuild globally:

npm install --global esbuild

If esbuild is not found globally, PhpSPA falls back to npx which will download it automatically (slower on first run).

Disabling esbuild

If you prefer faster compression time with less aggressive minification, or if you encounter issues with esbuild in your environment, you can disable it:

<?php
use PhpSPA\App;

$app = new App($layout);
$app->disableMinificationWithEsbuild();

Trade-off

Disabling esbuild means JavaScript will be minified using the built-in C++/PHP minifier, which currently provides less compression. It is recommended to keep esbuild enabled for production use.

Minifier Speed Compression Quality Tree-Shaking Bundling
esbuild (default) Fast ⭐⭐⭐ Excellent ✅ Yes ✅ Yes
Built-in C++/PHP Faster ⭐ Basic ❌ No ❌ No

📂 Custom Compressor Library Path

You can specify an absolute path to the native compressor shared library. This is useful if the library is in a non-standard location or you want to use a specific version.

<?php
use PhpSPA\App;

$app = new App($layout);
$app->setCustomCompressorLibraryPath('/path/to/libcompressor.so');
export PHPSPA_COMPRESSOR_LIB="/path/to/libcompressor.so"
<?php
// Or set it in PHP before creating the App
putenv("PHPSPA_COMPRESSOR_LIB=/path/to/libcompressor.so");

$app = new \PhpSPA\App($layout);

Platform-specific library names

Platform Library File
Windows compressor.dll
Linux libcompressor.so
WSL libcompressor-wsl.so
macOS libcompressor.dylib

🔒 Force Native Compression

By default, PhpSPA automatically falls back to PHP compression if the native library is unavailable. Use forceNativeCompression() to enforce native-only mode — the app will throw an exception if the library cannot be loaded.

<?php
use PhpSPA\App;

$app = new App($layout);
$app->forceNativeCompression();

Use with caution

Only enable this in environments where you are certain the native library is available. If the library fails to load, your application will throw a RuntimeException instead of falling back to PHP compression.

<?php
$app->forceNativeCompression();
$app->setCustomCompressorLibraryPath('/opt/phpspa/libcompressor.so');
<?php
// Let PhpSPA auto-detect and fallback gracefully
// No need to call forceNativeCompression()

🧩 Complete Configuration Example

<?php
use PhpSPA\App;
use PhpSPA\Compression\Compressor;

$app = new App($layout);

// Force native compression (no PHP fallback)
$app->forceNativeCompression();

// Point to a specific library build
$app->setCustomCompressorLibraryPath(__DIR__ . '/bin/libcompressor.so');

// Use extreme compression with Gzip
$app->compression(Compressor::LEVEL_EXTREME, true);

// esbuild is enabled by default, but you can disable it:
// $app->disableMinificationWithEsbuild();

$app->run();

Method Chaining

All configuration methods return $this, so you can chain them:

<?php
$app->forceNativeCompression()
    ->setCustomCompressorLibraryPath('/path/to/lib.so')
    ->compression(Compressor::LEVEL_EXTREME, true)
    ->run();