DEV Community

Süleyman Özgür Özarpacı
Süleyman Özgür Özarpacı

Posted on

How to Minify and Cache CSS & JS Files in Laravel

In modern web development, speed and performance are crucial for delivering a seamless user experience. One of the most effective techniques for optimizing performance is minification. Minification involves removing unnecessary characters from CSS and JavaScript files—such as whitespace, comments, and line breaks—without affecting their functionality. This process reduces file sizes, leading to faster load times, lower bandwidth consumption, and an overall improved user experience, especially for those on slower networks.

While tools like Laravel Mix or Vite are often used to manage and optimize assets, there are scenarios where these tools may not be applicable—such as when working with files provided by users or external sources. In such cases, manual optimization becomes necessary. In this article, we'll demonstrate how to optimize and stream these files directly using PHP, focusing on implementing minification in a Laravel project with the help of the matthiasmullie/minify package.

Step 1: Install the matthiasmullie/minify Package

To get started, install the matthiasmullie/minify package via Composer. This package provides a simple API for minifying both CSS and JavaScript files.

composer require matthiasmullie/minify
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a Minification Route

Next, add the following route to your web.php file. This route will handle requests to minify any CSS or JS file and serve the minified content, caching the result for improved performance.

use Illuminate\Support\Facades\Cache;
use MatthiasMullie\Minify\CSS;
use MatthiasMullie\Minify\JS;

Route::get('minify/{any}', function ($any) {
    $path = public_path($any);

    // Cache the checksum of the file
    $checksum = Cache::remember("file_checksum:{$path}", 60 * 24 * 365, function () use ($path) {
        return md5_file($path);
    });

    // Cache the file content based on the checksum
    $content = Cache::remember("file_content:{$checksum}", 60 * 24 * 365, function () use ($path, $any) {
        $extension = pathinfo($any, PATHINFO_EXTENSION);

        switch ($extension) {
            case 'css':
                $minifier = new CSS($path);
                $minifiedContent = $minifier->minify();
                return ['content' => $minifiedContent, 'headers' => ['Content-Type' => 'text/css']];
            case 'js':
                $minifier = new JS($path);
                $minifiedContent = $minifier->minify();
                return ['content' => $minifiedContent, 'headers' => ['Content-Type' => 'application/javascript']];
            default:
                return ['content' => file_get_contents($path), 'headers' => ['Content-Type' => 'text/plain']];
        }
    });

    // Set content and headers
    $response = response($content['content'], 200, $content['headers']);

    // Set Cache-Control, Expires and ETag headers for browser caching
    $cacheDuration = 60 * 24 * 365; // 1 year in minutes
    return $response->header('Cache-Control', "public, max-age=" . ($cacheDuration * 60))
        ->header('Expires', now()->addMinutes($cacheDuration)->toRfc7231String())
        ->header('ETag', $checksum); // ETag for validation
})->where('any', '.*')->name('themes_file');
Enter fullscreen mode Exit fullscreen mode

Step 3: Usage

Once you've followed the steps above, you can start using the minification feature by updating your HTML references. For example, if you have the following CSS and JavaScript references:

<link rel="stylesheet" href="/css/style.css"/>
<script type="text/javascript" src="js/main.js"></script>
Enter fullscreen mode Exit fullscreen mode

You will need to modify them to point to the minified versions as follows:

<link rel="stylesheet" href="/minify/css/style.css"/>
<script type="text/javascript" src="/minify/js/main.js"></script>
Enter fullscreen mode Exit fullscreen mode

After the first request, your CSS and JavaScript files will be minified and cached within your application. Additionally, the user's browser will cache these files, significantly reducing load times on subsequent visits. This caching mechanism ensures both server-side and client-side performance improvements.

Step 4: Key Considerations

This route performs two main tasks: it minifies the requested file (CSS or JS) and caches the result for quicker responses in future requests. The use of ETag and Cache-Control headers ensures that the browser can cache these assets for up to one year, reducing server load and speeding up content delivery.

However, this is just a basic implementation. To improve readability and maintainability, you can further optimize the code using design patterns like the Strategy Pattern or leverage a more robust asset management tool. Laravel Mix or other bundlers like Webpack can also be integrated for more complex use cases.

Conclusion

Minification is a simple yet effective way to boost your website's performance by reducing file sizes and improving load times. With Laravel and the matthiasmullie/minify package, you can quickly implement minification and caching for your CSS and JavaScript files. While this article demonstrates a basic implementation, consider exploring more advanced optimizations and design patterns to ensure your application remains maintainable as it scales.

Top comments (0)