Improve Drupal web site performance by aggregating CSS files

Technologies: Drupal 5+

Improve performance by combining multiple small CSS files into one large file using Drupal's CSS aggregation feature. The feature removes white space, enables better compression, and reduces browser-server communications overhead.

Introduction

Drupal's modularity enables site administrators to drop in modules to add features. Each enabled module may add a CSS file to style content it generates. The site's theme also adds CSS files. For a complex site, there may be a dozen or more CSS files total. This article looks at Drupal 5's new CSS aggregation feature and how it can improve performance by reducing file size and communications overhead.

Step 1: Enable CSS aggregation

Enable CSS aggregationDrupal's default installation does not enable CSS aggregation. To turn it on, log in as the site administrator, go to the "Administer" pages and select the "Performance" page under "Site configuration". Scroll down the page and click on the "Enabled" checkbox for "Aggregate and compress CSS files". Save the configuration and you're done.

With the feature enabled, Drupal concatenates module and theme CSS files into a single large CSS file. The file is stored in the "files" directory for your site. Thereafter, every web page includes this single large file instead of a zillion smaller ones. If you change the modules you use, or select a different theme, the aggregated CSS file is automatically updated.

Drupal also removes unnecessary white space (spaces, tabs, and carriage returns) in the CSS files as it aggregates them. This reduces the file size a bit, saving on download time.

If you need to edit your theme, be sure to temporarily disable aggregation while you're editing. When you're done, re-enable aggregation to rebuild the combined CSS file and incorporate your theme changes.

Step 2: Enable CSS compression

If you haven't already, enable text file compression in Apache. This will automatically compress all HTML, CSS, and JavaScript files sent by Drupal.

CSS file size results

The table below shows total CSS file sizes for simple and complex test web sites (see Specifications for Drupal web site testing), uncompressed and compressed by mod_gzip in Apache. White space removal alone reduced CSS file size by 20%. A single large CSS file compresses better than multiple smaller ones. White space removal, aggregation, and compression together reduced CSS file size by over 80%.

Test Simple site Complex site
Original 26,980
(100%)
49,188
(100%)
Compressed
orginal
7,637
(28%)
14,301
(29%)
Aggregated 21,340
(79%)
39,190
(80%)
Aggregated &
compressed
5,249
(19%)
6,636
(13%)
CSS file sizes using aggregation

CSS load time results

The table below shows total CSS file load times for the simple and complex test sites. Times are measured while using the Charles proxy server to throttle network speeds down to the 64 Kbytes/sec common for a site served over a cable modem. Aggregation and compression reduced CSS file load times by 85%.

Test Simple site Complex site
Original 5.994 sec
(100%)
10.422 sec
(100%)
Compressed
orginal
1.958 sec
(33%)
4.341 sec
(42%)
Aggregated 3.644 sec
(61%)
6.453 sec
(62%)
Aggregated &
compressed
0.924 sec
(15%)
1.461 sec
(14%)
CSS file load times using aggregation

The reduced load times are the result of three benefits of aggregation:

  • White space removal makes files smaller.
  • Aggregated files compress better, making files smaller still.
  • Browser-server communications overhead is less for one file than for multiple files.

The last benefit is harder to measure. For each file needed by a web page, the browser issues an HTTP (Hyper-Text Transfer Protocol) request to the server to ask for the file. That request is about 500 bytes long. The server answers with an HTTP response, taking another 500 bytes. For small CSS files (and most Drupal module CSS files are very small), this browser-server communications can take as much time as sending the file itself. Aggregation reduces the number of these requests, and the time spent doing them.

After a visitor views the first page at a web site, their browser caches CSS and image files for quicker use on the next page. However, even when files are cached, the browser still needs to check with the server on each one to be sure the browser has the most recent copy. If so, it uses the file in it's cache. If not, it downloads a fresh copy. This communications between the browser and server requires an HTTP request and response for every file on every page load, even if the cached files are used. That takes time. With aggregation, this communications time is reduced to that for a single CSS file check instead of a dozen or so.

Conclusions

Drupal's CSS aggregation removes white space and concatenates together theme and module CSS files. The resulting data is 20% smaller and compresses better. With white space removal, aggregation, and compression, CSS file load times are reduced by 85%.

However, CSS file load times are just part of the total page load time experienced by a visitor to your site.  The HTML for the web page certainly takes time too, as do all the images for your site's theme and the content itself.  The table below shows page load times for the entire home page of our test sites, including HTML, CSS, and image files.  Enabling the PHP script cache, MySQL query cache, and Drupal page cache help a lot.  Adding CSS aggregation and compression improves overall page load times further, but the load times are still a bit long and the sites will feel sluggish to visitors.

Test Simple site Complex site
Unoptimized 10.473 sec 20.676 sec
Enable script cache 9.412 sec 18.060 sec
Enable query cache 8.709 sec 14.748 sec
Enable page cache 6.725 sec 10.527 sec
Enable CSS aggregation 5.819 sec 8.278 sec
Enable text compression 3.581 sec 3.156 sec

What to do next

Even with CSS file aggregation and compression, page load times are still 3-4 seconds. This is way too long. For good usability, we need to be under 1 second.

Nadeau software consulting
Nadeau software consulting