3

I've read several articles throughout the web about removing query strings from static resources, in the template.php file, after I saw a recommendation to do so in a forum, for better page-loading time in Drupal.

All of the articles I've seen lacked some didcatance in the following points:

  1. Why should one remove Query strings for better loading times? I've never seen them in any URL of any my site's pages, and, I don't understand why would their appearance in a URL effect in any shape or form the loading time of a site's page (that deals more to image-optimization, bandwidth, etc).

  2. What is a static resource in Drupal? Cache is something dynamic so I'm guessing it's not the cache itself. So what is it?

  3. Where should I put the following code of this JavaScript function, at the start of the file, at the end, or between any special segments? It wasn't clear from none of the articles.

    /**
     * Implements template_process_html().
     */
    function MYTHEME_process_html(&$variables) {
      $variables['styles'] = preg_replace('/\.css\?.*"/','.css"', $variables['styles']);
    }
    
3

The only reason you'd want do this is to remove any cache busting query parameter. These are query parameters that are appended to a URL (e.g. www.example.com/js/some_file.js?b= 1433781670 & www.example.com/css/some_file.css?b= 1433781671 ) to prevent browser caching.


As the tutorial probably explained, you'd only want to do this for static resources (i.e. any web resource like a CSS/JS/Image file that will never change) so that the browser will cache the static resource.

As for the template question you can place the MYTHEME_processs_html() function anywhere in template.php (if you don't have one, create it). On top of that, the only thing you'd need is to replace MYTHEME with the short name of your theme and flush your theme cache.

If you're new to Drupal I'd recommend avoiding this for now; unless you're sure there's only static CSS stylesheets that can safely have its cache-busting query string removed, you can end up with a scenario where modules/themes aren't displaying correctly because the cache busting query parameter was needed.

  • A best answer one could get - Just one little question to make sure I understand right... What is "css\js\image file that will never change" I tend to change my CSS much... Do you mean that in browsing it won't be changed? – JohnDoea Jun 8 '15 at 18:46
  • 1
    Yes, if your browser decides to retrieve from cache, it could miss a change that happened server side. The whole point of cache busting query parameter is to ensure this never happens. That's why I suggested avoiding this; you should let the module/theme developers decide what/when to break caching. – Shawn Conn Jun 9 '15 at 3:12
  • The page can change the link URLs when the resources linked to change. So far so good. The problem is that those URLs are being constructed using the query parameter. It would be better to put it in the path, and have it stripped out again using a RewriteRule in .htaccess, or something equivalent (e.g. for nginx). – mc0e Nov 10 '15 at 10:34
  • The biggest problem with the "cache busting" query string is that it makes it hard to use certain developer tools. This is not a minor problem. It's a problem where I think some of the Core dev people are simply not listening when developers cry out in frustration. This really should be an admin setting. – Torenware Networks Dec 9 '15 at 2:53
  • Works like charm for Drupal 7 but when I use the code for Drupal 8 via mytheme.theme and flush cache, the site crashes. I can't find documentation on this anywhere. I would thank you dearly to update the comment. I have yet to learn enough on URLs and Regex to solve it myself will gladly give the bounty for an update. – JohnDoea Dec 6 '16 at 14:11
1
+50

The query parameters on the CSS and JS resources in Drupal are used to clear browser cache when the file changes on the server-side. But in normal circumstances, the query parameters will remain the same for all requests, thereby allowing the browser to cache the resources.

Removing these parameters might create problems if you ever decide to edit the CSS file in the future and someone already has the file cached on their browser. Such a user will continue to see the old CSS file (which you changed) until the cache lifetime expires.

What you can set caching rules for static resources in your .htaccess, which, in my opinion would be a better thing to do (cause there is a reason why Drupal devs did additional work to add those query parameters in the first place).

# Set expiry for static files
<FilesMatch "\.(?i:gif|jpe?g|png|ico|css|js|swf|ttf|otf|woff|svg)$">

  <IfModule mod_expires.c> 
    ExpiresActive On
    ExpiresDefault "access plus 1 seconds"
    ExpiresByType text/html "access plus 1 seconds"
    ExpiresByType image/x-icon "access plus 6 hours"
    ExpiresByType image/gif "access plus 6 hours"
    ExpiresByType image/jpeg "access plus 6 hours"
    ExpiresByType image/png "access plus 6 hours"
    ExpiresByType text/css "access plus 6 hours"
    ExpiresByType text/javascript "access plus 6 hours"
    ExpiresByType application/x-javascript "access plus 6 hours"

    ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
    ExpiresByType application/x-font-ttf "access plus 1 month"
    ExpiresByType application/x-font-opentype "access plus 1 month"
    ExpiresByType application/x-font-woff "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
  </IfModule>

  <IfModule mod_headers.c>
    Header set Cache-Control "public, max-age=21600"
  </IfModule>

</FilesMatch>

Of course, you can remove the lines you do not need or add new ones as per your requirements. Hope it helps!

  • I already use mod expires (tested and it's working), but I still get a GTmetrix comments about disabling cache busting query strings... – JohnDoea Dec 7 '16 at 3:54
1

I solved it with this code:


use Drupal\Core\Asset\AttachedAssetsInterface;

/**
* Implements hook_css_alter().
*/

function YOURTHEMENAME_css_alter(&$css, AttachedAssetsInterface $assets){

     foreach ($css as &$file) {
    if ($file['type'] != 'external') {
      $file['type'] = 'external';
      $file['data'] = '/' . $file['data'];
    }
  }

 }


/**
* Implements hook_js_alter().
*/

function YOURTHEMENAME_js_alter(&$javascript, AttachedAssetsInterface $assets){

     foreach ($javascript as &$file) {
    if ($file['type'] != 'external') {
      $file['type'] = 'external';
      $file['data'] = '/' . $file['data'];
    }
  }

 }

Put the code into YOURTHEMENAME.theme file.

It works perfect on Drupal 8.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.