Implements cache for tailwind output

Created on 19 November 2024, 2 months ago

Problem/Motivation

Tailwind JIT works nicely with Internal Cache Page module. But when there're dynamic query parameters in the request, the internal cache will consider it as a new request, hence trigger the tailwind compiler. However, page content might still be the same with different query params, e.g ?utm=tracking_source, so unnecessary recompilation bring high pressures to the server.

Proposed resolution

1. Extract the css classes from the content
2. Sort the css classes with alphabet
3. Generate a cache key with classes hash
4. Cache tailwind's output, so next time when the same set of classes are requested, return the cache result immediately

It can also benefit authenticated visitors, since it can work without internal page cache.

Works to be done

Right now only element classes are extracted. Classes in javascript or json string are not handled.

Feature request
Status

Active

Version

1.0

Component

Code

Created by

🇨🇳China stjuan627

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @stjuan627
  • Status changed to Needs review 2 days ago
  • 🇳🇿New Zealand garethhallnz

    I too have run into a similar issue; for me most of out users are authenticated and Drupal's internal page cache module and even the dynamic page cache module does very little to help. Reverse proxy cache like varnish will obviously help but not all sites have access to such systems.

    I have built on top of @stjuan627 patch and expanded on his work.

    Why This Feature is Needed

    During my testing, I observed that while Drupal’s internal page cache works well for anonymous users, performance for authenticated users suffered significantly. On average, page load times for authenticated users were 2-3 seconds slower due to the lack of caching for compiled Tailwind CSS. This is because authenticated users often bypass Drupal’s internal page cache, leading to repeated CSS compilation for every request.

    The new caching feature addresses this issue by:

    Improving Performance for Authenticated Users:
    - By caching compiled CSS, authenticated users no longer experience the overhead of repeated CSS compilation, resulting in faster page load times.
    Enhancing Performance for Anonymous Users:
    - While anonymous users already benefit from Drupal’s internal page cache, this feature adds an additional layer of optimization by caching compiled CSS separately. This reduces the time required to generate the final HTML response.
    Scalability:
    - High-traffic sites, especially those with a mix of anonymous and authenticated users, will see significant performance improvements, as the caching mechanism reduces server load and improves response times.

    New Features

    1. CSS Caching for Improved Performance

    I’ve added a caching layer to store compiled Tailwind CSS, significantly reducing the need for repeated compilation and improving response times for subsequent requests. Key highlights include:

    Configurable Cache Settings:
    - Enable or disable CSS caching via the theme settings form.
    - Set a cache lifetime, with options ranging from 1 hour to 90 days or permanent storage.
    - Choose a hashing algorithm for cache key generation (default: `xxh3` for optimal performance).

    Automatic Cache Invalidation:
    - The cache is automatically cleared when theme settings are saved or when the cache is manually cleared via Drupal’s cache administration page.

    Efficient Cache Key Generation:
    - Cache keys are generated based on the unique CSS classes found in your content and the active theme, ensuring accurate and efficient caching.

    2. Extraction of Unique CSS Classes

    To optimize CSS compilation, I’ve introduced a new method to extract and deduplicate CSS classes from your HTML content. This ensures that only the necessary CSS is compiled and cached, reducing overhead and improving performance.

    3. Enhanced Theme Settings Form

    The theme settings form has been updated to include new options for managing the caching feature:
    - A new section allows administrators to configure caching settings, including enabling/disabling caching, selecting a hashing algorithm, and setting the cache lifetime.

    Improvements

    Dependency Injection:
    - The `HttpMiddleware` class now injects the `CacheBackendInterface` service, enabling seamless integration with Drupal’s caching system.

    Code Refactoring:
    - Added helper methods (`injectStyleTag()` and `generateCacheKey()`) to streamline the caching and CSS injection process.

    Performance Optimization:
    - Reduced redundant CSS compilation by leveraging cached results, improving response times for high-traffic sites.

    How to Use the New Features

    1. Enable Caching:
      - Navigate to the theme settings form (`/admin/appearance/settings/[your_theme]`).
      - Under the "Experimental features" section, enable CSS caching and configure the cache lifetime and hashing algorithm.
    2. Monitor Cache Performance:
      - Use Drupal’s cache administration page (`/admin/config/development/performance`) to monitor and clear the cache as needed.
    3. Test and Optimize:
      - Test the caching feature in a staging environment to ensure compatibility with your site’s configuration.
      - Adjust the cache lifetime and hashing algorithm based on your performance and security requirements.

    Backward Compatibility

    This release is fully backward-compatible with existing configurations. However, the caching feature is marked as experimental, so I recommend thorough testing before enabling it in production environments.

    Bug Fixes

    - Fixed an issue where redundant CSS compilation could occur for repeated requests.
    - Improved error handling during CSS compilation to ensure graceful fallbacks.

Production build 0.71.5 2024