Option to load CSS files directly via web server
-
Heya,
It’s great that W3 Total generates static html files to be loaded by the web server directly – this saves massively on PHP processing.
But I’m confused as to why the minify functions take what, in most themes, is a totally static file (JS and CSS) and then make that request dynamic – to be loaded via PHP processing.
One of the primary goals of the plugin is to reduce PHP processing and rely on the web server engine performance, so it seems conter-intuitive to then rely on PHP to serve what is clearly already static files.
It would be great if there could be (or perhaps is that I missed?) an option to output minified CSS to file so we’re not reliant upon PHP to serve it.
-
Hello @websavers
Thank you for reaching out.
Let me consult with the team and I’ll get back to you once I have more infoThanks!
Thanks @vmarko!
Hello @websavers
Thank you for your feedback.
Minify creates smaller versions of the CSS & JS files and caches them to be served by cache and not PHP.
When you enable Minify for CSS & JS using Disk, you can see cache files:wp-content/cache/minify/60d0b.js
wp-content/cache/minify/60d0b.js_meta
wp-content/cache/minify/60d0b.js_gzip
wp-content/cache/minify/60d0b.js_gzip_meta
wp-content/cache/minify/c096e.css
wp-content/cache/minify/c096e.css_meta
wp-content/cache/minify/c096e.css_gzip
wp-content/cache/minify/c096e.css_gzip_metaRewrite rules should them load the files if they exist.
This Apache rewrite block is part of W3 Total Cache’s minification feature. It conditionally serves pre-compressed minified CSS and JavaScript files from the cache directory based on the browser’s supported compression method (Brotli or gzip). Here’s a breakdown:
Overview
- Purpose:
- Optimize delivery of minified CSS/JS by serving pre-compressed versions when available, reducing bandwidth and improving load times.
- Context:
- This configuration is used in the
/wp-content/cache/minify/
directory where W3 Total Cache stores minified assets.
Here is the explenation
- Module Check & Setup:
# BEGIN W3TC Minify core <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /wp-content/cache/minify/
<IfModule mod_rewrite.c>
: Ensures the following rules only run if Apache’smod_rewrite
module is active.RewriteEngine On
: Activates the rewrite engine.RewriteBase /wp-content/cache/minify/
: Sets the base path for rewriting, pointing to the minify cache folder.
Let me know if this helps!
Thanks!
Hey @vmarko,
What I’d like to see is the option to directly reference these files in the cached page HTML rather than use rewrites to load them.
This will make it compatible with nginx reverse proxies that pick up static files directly, prior to passing on to apache+php, as well as automatic 404 handling that’s used to reduce server load on 404s (ie: 404 on a static file extension results in simple reply, not dynamic one).
Any chance of getting that as an option in the settings?
Right now, when I enable minify using W3, all my CSS files become a 404 because of those other optimizations, but other caching/minify plugins don’t do it this way, so they don’t end up with a 404.
Hello @websavers
Thank you for your feedback and your suggestion.
Ah, this clarifies the behaviour your are describing. I need to check this, however, the way that W3TC does this is better for performance.
Let me check why these issues may occur depending on the environment and see if there is anything we can do about this.Thanks!
Hey @vmarko
I mean it’s definitely better than what I was saying above! And I see what you’re saying about the conditional serving – that could indeed improve performance in some cases.
While you’re checking on that, I’ll see if I can get some nginx equivalent rules to apply specifically for this case.
The tricky thing is we use Plesk which has its own nginx static file handling option. When it’s enabled, no additional nginx rules can override it (from what I’ve tried), so to get CSS and JS rewrites to work with Plesk+nginx we have to instruct users to exclude CSS and JS from that static file handling option, and then also add custom rewrites to handle it. It’s possible, but just not something that is particularly user friendly.
Your rewrites 100% push all static files to PHP like I indicated at the start. Here’s the complete rewrite code:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wp-content/cache/minify/
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=APPEND_EXT:_gzip]
RewriteCond %{REQUEST_FILENAME}%{ENV:APPEND_EXT} -f
RewriteRule (.*) $1%{ENV:APPEND_EXT} [L]
RewriteRule ^(.+\.(css|js))$ /index.php [L]
</IfModule>For optimal performance these should *never* rely on PHP. Think about scenarios where there’s thousands of new simultaenous visitors. nginx can handle that kind of traffic for static files all on its own, but these rewrites make it so that nearly every page load of every single static file requires PHP to serve. (Minus browser cached of course, but this doesn’t help with there’s a lot of unique traffic)
This is why I’m asking for the option for a direct link to the file on disk in the static HTML output – doing it that way will ensure better performance AND simpler compatibility with Plesk’s default nginx config.
Keep in mind that this is the same priciple as why you already have static HTML page output working that way – to avoid PHP processing. It should be the same for static files that were like that from the start – it shouldn’t be *more* PHP processing necessary than before W3 got involved.
Hello @websavers
Thank you for your feedback.
I’ll bring this up with the teamThank you for your suggestion
Thanks @vmarko
Your notes above indicate that there should be static files in
wp-content/cache/minify/
And I’m finding now why this isn’t the case for me. Those files only exist if I turn off “Rewrite URL structure” which uses requests like this:
https://schelew.com/?w3tc_minify=a5ff7.css
That definitely gets passed to PHP becuase it’s a query string.
If I then disable “Rewrite URL structure”, the static files remain and are loaded by the web server (great!) until the minified cache is cleared, at which point they are again not written to the minify folder, so they can never be loaded by the web server (not so great).
With Rewrite URL structure ON someone needs to request those static resources once to get them generated in the first place, then after that first load of the file, they’re fully static. This means only the first load would require PHP.
This method of JS/CSS file generation creates problems in a performance optimized environment because of two optimizations:
- Those using Plesk with nginx’s static file handling enabled may never hit the rewrites, and
- Those using an apache 404 handler for static files that keeps those requests lightweight (to avoid repeated 404s bogging down the server/website) will not hit those rewrites and instead will be served a 404.
I propose an option where you disconnect the static file generation process from loading the static file itself. Instead when a page’s cache file is generated, *also* generate connected static files at the same time. This way you don’t rely upon rewrites for the static files to work for *any* static file loading to function in these environments.
Meantime I’ll get working on adding the minification rewrites in nginx, as I now see that with the right config, it doesn’t *need* to hit PHP every time – just the first load after new minified files are generated.
Hello @websavers
Than you for your feedback and I am sorry for the late reply
So if I understand correectly, the static files are handled by the Nginx and this is why the problem occurs, and you need to manually add the rewrite rules for minify to the nginx in order for this to funcktio proprely in your environment?Thanks!
Hey Mario,
As you probably know, the default for most hosting environments with WordPress is to pass all non-existent files directly to index.php.
This presents a performance problem: what happens if you’ve got one (or more) static file(s) that’s included one very page and suddenly turns into a 404? Every single page load is going to generate PHP processing, for absolutely nothing: simply to say “this file doesn’t exist”. Now magnify this on a very busy site and you’ve got dozens, maybe hundreds of PHP processes being launched just to say a file doesn’t exist. I’ve seen this in practice and it’s not pretty.
It makes no sense to do that.
And so we – along with other WP performance optimized hosts – have either server-wide nginx or apache rules (it was easier to do it in apache for us) that explicitly check for 404s for static files and immediately serve a simple 404 page rather than allow it to be passed to PHP.
The problem, as I’ve now discovered, is that W3’s minification system requires the first load of any css or js file to be sent to PHP, which the above noted rules will not allow. This hasn’t been a problem with other optimization plugins because they all appear to generate their minified files when the *page* is generated, not when the static file is loaded.
I’ve written an exception for this into our apache rules that detects if the static file request is for a non-existent file within a ‘minify’ folder and sends it through to PHP after all. I’d rather not have to do this though. And I suspect you’ll find better support for your minification system if you’re able to link the minfication process to the page and not the static file load.
- You must be logged in to reply to this topic.