Four Kitchens
Insights

Use AdvAgg Information tab to debug or optimize CSS and JS aggregates in Drupal 7

4 Min. ReadDevelopment

In a previous article about using AdvAgg to inline critical path CSS, I briefly mentioned an optional step to reducing the number of bundles produced by the aggregator. I’d like to walk through that process now, using the Fourword as an example.

If you’re not familiar with the Advanced CSS/JS Aggregation module for Drupal (called AdvAgg for short), it is the go-to solution for frontend performance optimization in Drupal. This article describes the process for AdvAgg 7.x-2.14. Older or newer versions might have slightly different configuration options.

Use-case: removing files from an aggregate

In my situation, I had an issue where using the AdvAgg Bundler was producing more than one aggregate for the public visitors to the site. The extra aggregates were coming from sources that, upon inspection, were found to be completely unused by visitors to the site. I decided the simplest solution was to suppress them for anonymous users, completely eliminating the aggregates that were composed of these files.

First, I went to /admin/config/development/performance/advagg/info to load the Information tab. This page has lots of options but we’ll focus on one section for our use-case: the last section which is labeled “Get detailed info about an aggregate file.”

Screenshot of AdvAgg Detailed Information section
Screenshot of AdvAgg’s detailed info tool.

Identify files within aggregates

The interface is simple: there’s a text field for you to enter a file name. You can enter a specific file that might be used on your site (e.g. modules/system/system.base.css) or you can enter an aggregate filename. Assuming you’ve already got AdvAgg enabled, entering aggregate filenames will be the most useful. Go ahead and enter the filename of the unwanted aggregate. It will be a lengthy filename made up of random letters and numbers.

I’d suggest loading your site in incognito (in Chrome) or Private Browsing mode (in Firefox) if you want a quick method of looking at the site as an anonymous visitor. This will be more reliable than looking at the aggregates generated for a logged-in admin, which might be quite different.

Once you’ve pasted the aggregate filename and clicked the Lookup Details button, AdvAgg will return all the information it has about this aggregate: the AdvAgg settings associated with it, the hooks which caused it to be created or altered into its current state, and the files which were combined to create it. Let’s focus on the files, which are labeled [files] in the Array that AdvAgg returns. Here’s a sample of the output you’re looking for:

[files] => Array
  (
    [sites/all/modules/contrib/fences/field.css] => Array
      (
        [filesize] => 457
        [mtime] => 1407138086
        [filename_hash] => RMBNT_K3MAIy2ar1d8XH5YHHoHuiA6hpuYF_vFaZJxM
        [content_hash] => GMyvgHJxaIu9_qs6iF6TOcu_cN4fb3wb5TI3C_020iE
        [linecount] => 6
        [data] => sites/all/modules/contrib/fences/field.css
        [fileext] => css
        [cache_id] => advagg:file:RMBNT_K3MAIy2ar1d8XH5YHHoHuiA6hpuYF_vFaZJxM
        [group_hash] => 00000003 ypA6vopnjoro5_v18jPM_NMJh2Xy9NfpYXkIqcv8_TI
      )
  )

Each item in the array has a filename as an index. That’s the information we’re interested in at the moment. Scanning the list, I noticed that my unwanted aggregate contained CSS from a few familiar modules: ctools, views, the date and date_popup module, and a few others. Since I’m familiar with the internals of the Fourword, I know that a normal visitor will never see any of these styles; there are no date popups, no auto-complete boxes, or ajax requests which use that characteristic Drupal throbber. They are safe to completely remove for anonymous users.

Note: AdvAgg can’t tell you if a visitor needs the files it finds; you must determine its relevance based on knowledge of your specific Drupal implementation. Be sure to test your work thoroughly to make sure it’s not causing problems for your users!

Removing CSS files within Drupal

Once I determined which files to remove for my visitors, I went back to fourword_theme where I previously inlined our critical CSS. In this case the changes are all related to a particular theme, but if you prefer to use a custom module that’s a good home for this code too:

<?php

/**
 * Implements hook_css_alter().
 *
 * Alter CSS to optimize our theme.
 */
function fourword_theme_css_alter(&$css) {
  global $user;

  $exclude = array(
    // Contrib CSS
    'sites/all/modules/contrib/date/date_api/date.css' => FALSE,
    'sites/all/modules/contrib/date/date_popup/themes/datepicker.1.7.css' => FALSE,
    'sites/all/modules/contrib/views/css/views.css' => FALSE,
    'sites/all/modules/contrib/ctools/css/ctools.css' => FALSE,
    'sites/all/modules/contrib/panels/css/panels.css' => FALSE,
  );

  // Exclude unnecessary CSS for anonymous users.
  if ($user->uid == 0) {
    $css = array_diff_key($css, $exclude);
  }
}

My logic is luckily quite simple: exclude the files for anonymous users. Our content editors and other logged-in users still need these styles, since we make use of them for authoring posts and other Drupal admin tasks.

Since the $css variable is passed by reference into all alter hooks within Drupal, there’s no need to return anything; the CSS is now permanently altered for this page load.

Debugging gotchas

During the course of debugging, you’ll find yourself clearing the cache often in order to see the new aggregates. Don’t forget to supply the new filename to AdvAgg once you’ve done so. If you check the same filename again, it will show you the same list of files and it might seem like your changes didn’t take.

When you’re satisfied, clear that cache one more time to be sure that visitors are getting the latest and greatest.. your page should load with one less aggregate! High five!