A web site's theme includes CSS files to style the site and images to add decoration. Improve Drupal web site performance by simplifying the theme to use fewer styles and images.
Table of Contents
- Introduction
- Step 1: Enable all system-wide performance improvements
- Step 2. Use a simpler standard theme
- Step 3. Disable unused theme features
- Step 4. Create your own theme
- Don't depend upon the browser cache
- Use a single CSS file
- Don't duplicate CSS default styles in Drupal and HTML
- Use CSS shorthands and style grouping
- Use the fewest images possible
- Use images that compress well
- Load time results
- Conclusions
- What to do next
- Further reading
Introduction
Drupal 5's default theme is "Garland", which looks nice but it includes a big style sheet and multiple decorative images. These take time to send to visitors of your site. While the files can be cached by the visitor's browser, that first visit to the site is still slow. Unless your visitors come to your site frequently, your CSS and image files won't stay in the browser cache long enough and your visitors will have to download them all over again on the next visit, and the next, and the next. Soon enough they will tire of long download times to visit your site. First-time visitors may not tolerate it at all. To make a good first impression, and to keep your repeat visitors happy, it is important to keep page load times as short as possible by reducing the amount of CSS and image data that they have to download.
Usability studies have found that visitors are impatient. They expect a fast response from every site they visit. With a page load time under 1 second, visitors find the experience fluid, but if the load time increases to 4 seconds, retail visitors begin to leave for a faster site. If times stretch to 10 seconds, most visitors will give up on your site. So, there's our goal: a download time under 4 seconds at all costs, and preferably at or under 1 second.
This article looks at the page load times of the standard Drupal themes and at what makes them fast or slow. It provides guidelines on how to simplify a theme to achieve better first-visit performance and achieve fast load times, even when serving the site over a cable modem or DSL connection.
Step 1: Enable all system-wide performance improvements
Before worrying about theme speed, first enable all of the caching and compression features of Drupal, MySQL, PHP, and Apache. This gives you a fast starting point for further optimizations:
- Install and enable a PHP script cache. Avoid re-compiling Drupal's PHP scripts on every page load by saving compiled scripts in a cache.
- Enable MySQL's query cache. Avoid re-executing identical database queries on every page load by saving common query results in a cache.
- Enable Drupal's page cache. Avoid re-building identical web pages on every page load by saving common pages in a cache.
- Enable Drupal's CSS aggregation. Avoid sending a zillion small CSS files by combining them into one bigger file with white space removed. The bigger file compresses better and is faster for the visitor's browser to keep uptodate.
- Enable Apache's text file compression. Reduce the size of HTML, CSS, and JavaScript files so that they are quicker to send.
The table below shows page load times for our simple and complex test web sites (see Specifications for Drupal web site testing). These times are for loading the site's home page for a first-time visitor where none of the site's CSS or image files are in the visitor's browser cache. The Charles proxy server is used here to throttle speeds down to the 64 Kbytes/sec common for sites served over a cable modem or DSL connection.
|
![]() |
Without optimizations, the visitor's page load time is 10-20 seconds. This is very bad. Few visitors would bother waiting that long. With optimizations, the load time is under four seconds. That's a huge improvement, but we still need to get to one second to make the site feel snappy and responsive.
Beware of calling "under four seconds" good enough. The times above were performed on a dedicated network without competing traffic from the rest of the Internet, and without DNS host name lookups. Your site visitors don't have it that good. DNS lookups and Internet traffic can easily add several more seconds to the page load time. To keep the visitor's load time below four seconds, your site needs to be down to one or two seconds on its own.
Also note that Drupal's page cache only works for anonymous visitors. Logged-in visitors get custom-built pages, bypassing the page cache. In the table above, the page cache reduced load times by 2-3 seconds for our test sites. Add those seconds back into the load time once a visitor is logged-in. Since even logged-in visitors deserve short load times, your site needs to be under four seconds even with the page cache disabled.
Step 2. Use a simpler standard theme
A theme adds one or more CSS style sheets and images for page decoration. These take time to load into your visitor's browser. The table below lists the standard Drupal 5 themes and the number and size of the files they add to a page.
| CSS | Images | |||
|---|---|---|---|---|
| Theme | # | Size | # | Size |
| Blue Marine | 1 | 5,668 | 1 | 1,767 |
| Chameleon | 2 | 3,844 | 2 | 1,962 |
| Garland | 3 | 19,083 | 15 | 15,160 |
| Marvin (Chameleon fixed) | 1 | 3,128 | 2 | 4,426 |
| Minnelli (Garland fixed) | 4 | 19,420 | 15 | 15,160 |
| Pushbutton | 1 | 12,348 | 27 | 30,150 |
Drupal's default style sheets also include decorative images.
| Images | ||
|---|---|---|
| # | Size | |
| Drupal defaults | 10 | 5,001 |
The default "Garland" theme in Drupal 5 has a lot of CSS and images. "Minnelli" and "Pushbutton" are as bad or worse.
Fortunately, theme images only load if they are needed on a page. For example, "Pushbutton"s forum background images are only loaded if the page contains forum content. The most important images in a theme are the ones that must load for every page, such as header and general page backgrounds.
The table below reports page load times for our simple and complex test site home pages for the standard themes. Site optimizations remain enabled from step 1. The slowest themes are the ones with a lot of CSS and images, like "Garland" and "Pushbutton". The simpler themes have half the page load time.
|
![]() |
Step 3. Disable unused theme features
Drupal enables all themes to include a logo icon, a "favicon" for browser favorites lists, and text for a slogan and mission statement. Do you really need all of these? You can enable and disable these in Drupal's configuration pages:
- Log in as your site's administrator.
- Go to the "Administer" page.
- Select the "Themes" page under "Site building."
- On the theme list, select the "configure" link to the right of your theme.
- Check/uncheck features on the theme.
- Save the configuration.
- Reset your Drupal page cache (it doesn't reset on configuration changes):
- Select the "Performance" page under "Site configuration."
- Disable the page cache.
- Save the configuration.
- Re-enable the page cache.
- Save the configuration.
Chances are you'll want your own logo image instead of the default Drupal "drop" icon. Remember to keep the logo small and heavily compressed.
By default, Drupal enables a mission statement, but leaves it blank. Save a tiny bit of Drupal effort by disabling the slogan and mission statement. Most people skip these, or include them within the logo image.
The shortcut icon, or "favicon", is also optional. Some browsers use it in favorites/bookmarks lists. Though only 16x16 pixels, the icon's file format doesn't support compression, making the icon file about 1 Kbyte. Worse, some browsers (like Firefox) actually load the icon twice for every page. If this icon isn't a vital feature for your site, turn it off to save page load time.
- Don't uncheck "Shortcut icon" on the theme configuration. You'd think this would work, but it just forces the browser to default to looking for "/favicon.ico". If the file doesn't exist, the browser gets a 404 (not found) message on every request for the icon. And that actually takes more bytes than the icon file did, and it adds an entry to your web site's error log.
- Instead, leave "Shortcut icon" enabled but uncheck "Use the default shortcut icon".
- Type a "/" by itself as the "Path to custom icon". Browsers recognize this as meaning there is no favorites icon.
- Save the configuration.
Step 4. Create your own theme
Keep in mind that (1) you can download other free themes from Drupal's web site, and (2) you don't have to use any of them as-is. If you create your own theme, you can craft the look you want and use an amount of CSS and image data that makes sense for your site's network bandwidth. To create a new theme, copy an existing theme and start editing. The "Blue Marine" theme is a good starting point.
Here are a few things to keep in mind when creating your own theme...
Don't depend upon the browser cache
An often-repeated excuse for using big images is "It's OK because they'll be cached by the browser." Yes and no. Your site might be great, but it is unlikely that it is the only one your visitors go to. The files from other sites, along with yours, are all added to the visitor's browser cache. If they don't all fit, then the oldest files are deleted to make room for new ones. If someone visits your site in the morning, by that afternoon your files are probably long gone from their cache. If they return to your site, they'll have to download them again. And so on, every time they return to your site. A browser cache mostly only helps if a visitor views several of your pages in quick succession before going elsewhere.
So, don't depend upon your files being in the browser cache. They probably won't be. Instead, make your site fast by using small CSS and image files. It'll be even faster if the files do happen to be in a frequent visitor's browser cache.
Use a single CSS file
During theme authoring, it can be convenient to split CSS into several files - perhaps overall layout goes in one CSS file, menu decorations in another, and background decoration in a third. This is handy during editing, but don't leave it this way. Drupal's CSS aggregation feature can only aggregate the main "style.css" file for your theme. Any files you include with CSS "@import" lines won't get aggregated. This forces your visitor's web browser to ask for each of them individually, which takes time.
For example, in the table in step 2 we compared the "Garland" theme with it's "Minnelli" derivative. The "Minnelli" theme uses a short "style.css" file with an "@import" line to include "Garland"s main style sheet. That one "@import" line prevents CSS aggregation and adds almost one second to the page load time. Other than this "@import", the two themes are practically identical.
So, put all your CSS into one "style.css" for your theme. Don't use "@import".
Don't duplicate CSS default styles in Drupal and HTML
Some theme authors brag that they like to copy all of Drupal's separate theme files into one big file, then tweak everything for their ultimate theme. This works, but remember that Drupal's own CSS files get downloaded anyway. If your theme has a copy of all of them, you've just doubled the CSS download size for your site.
Instead, keep your theme's CSS file brief by only including things that are different from the Drupal and standard HTML defaults. Don't duplicate style properties in Drupal or HTML's defaults.
Use CSS shorthands and style grouping
A few more ways to keep CSS short:
- Use CSS shorthands for setting multiple properties at once. For instance, use one "margin" line to set the top, right, bottom, and left margins all at once instead of using separate "margin-top", "margin-right", "margin-bottom", and "margin-right" lines. Shorthands exist for setting margins, padding, fonts, borders, backgrounds, and more.
Long way Shorter way div.this {
margin-top: 0;
margin-right: 10px;
margin-bottom: 1em;
margin-left: 10px;
border-top: 1px solid #CCC;
border-right: 1px solid #CCC;
border-bottom: 1px solid #CCC;
border-left: 1px solid #CCC;
}div.this {
margin: 0 10px 1em 10px;
border: 1px solid #CCC;
}
- Don't qualify classes and IDs with markup elements unless necessary. For instance, if you define a style class "this" and only use it on "div" elements, then you can safely refer to it as ".this" in the CSS file, instead of "div.this".
Long way Shorter way div.this {
margin: 0 10px 1em 10px;
}
div.that {
margin: 10px;
}.this {
margin: 0 10px 1em 10px;
}
.that {
margin: 10px;
}
- Group shared properties. For instance, if two styles use the same margin or font, then set both styles at once instead of duplicating the CSS to set them individually. Group style properties together by listing multiple classes or IDs, separated by commas, before the opening curly brace.
Long way Shorter way .this {
font-size: 1.1em;
font-weight: bold;
margin: 0 10px 1em 10px;
}
.that {
font-size: 1.1em;
font-weight: bold;
margin: 10px;
border-bottom: 1px solid #CCC;
}.this, .that {
font-size: 1.1em;
font-weight: bold;
}
.this {
margin: 0 10px 1em 10px;
}
.that {
margin: 10px;
border-bottom: 1px solid #CCC;
}
- Set properties broadly, then override for specific cases. For instance, don't set the same font, color, or line spacing repeatedly for every element. Instead, set the default choices for the whole page once on the "html" or "body" elements, then override them for special cases.
Long way Shorter way h1 {
font-family: arial, sans-serif;
color: #555;
}
h2 {
font-family: arial, sans-serif;
color: #559;
}
p {
font-family: arial, sans-serif;
color: #000;
}html, body {
font-family: arial, sans-serif;
color: #000;
}
h1 {
color: #555;
}
h2 {
color: #559;
}
Use the fewest images possible
Images are the worst offenders in page load times. Every background image, menu item bullet, or decorative icon takes time to download. To reduce page load times, reduce the number of images you use, and the size of those images.
For example, it is common practice in Drupal themes to use special menu item bullets for expandable menu groups. Each new kind of bullet requires another image file. Drupal's default bullet images are just 100-200 bytes each and they can be cached in your visitor's browser. However, on every page load the browser has to check in with the web server anyway to be sure that the image it has cached is still the current version. This takes time. In fact, the HTTP (Hyper Text Transfer Protocol) messages to and from the server for this check each take 500 bytes - more than double the size of the bullet image files! So, even though the image files are small and cached, they still slow down page load times.
For each image, ask yourself if it is really necessary? Do you really need custom menu item bullets, or will HTML's built-in standard bullets do? Do menu items even need bullets at all? Every image you add increases the page load time, adds more load on your web server, and forces your visitors to wait a bit longer to get a page. Minimize the use of images.
Use images that compress well
Complex detailed images don't compress well. For instance, GIF's compression scheme works great for horizontal runs of identical pixels, such as a solid background color, but its terrible for horizontal gradients or dithered dot patterns. If you design your theme to avoid such things, your background images will be much smaller and page load times will improve.
Load time results
The table below shows page load times for several variants of the "Blue Marine" theme:
- "Blue Marine" as-is.
- The theme, but with Drupal's three default menu bullet images disabled.
- All of the above, but with the favorites icon and mission statement extras disabled.
- All of the above, but with reduced CSS and HTML markup by deleting unused features: mission statement, primary links, secondary links, and RSS feed icon.
These theme changes reduce page load times another 30-50%. This is primarily from dropping the image files for menu bullets, the favorites icon, and the RSS feed icon.
|
![]() |
Conclusions
Using a simpler theme reduces the number of CSS and image files to download, and the size of those files. A simple theme, like "Blue Marine" has half the page load time of a complex theme like "Garland." Disabling Drupal's default menu bullet images, the favorites icon, and the RSS feed icon drops page load times 30-50% more.
The simpler theme with fewer images gives page load times around 1 second, which is better than the 3-4 seconds we started with. Is there anything more that we can do? The table below lists the file sizes for the files being downloaded for the home page of our test sites:
| File | Simple site | Complex site |
|---|---|---|
| Home page | 3,984 bytes | 5,692 bytes |
| Aggregated CSS | 2,987 bytes | 3,883 bytes |
| Logo image | 1,767 bytes | 1,767 bytes |
| Test.png (image in content block) | 662 bytes |
The CSS is about as small as we can make it, and there is only one theme image (the logo). Everything else is page content (including one content image on the complex site). To optimize even further, we'll have to look at the home page content itself.
What to do next
Some things to think about:
- Compress your images. For the images yhu keep in your theme, make sure they are as small as possible. Crop them tight and adjust compression parameters to make them as small as possible without creating noticeable image quality problems.
- Simplify web pages. Reduce the amount of text and markup on your site's pages to make them smaller and faster to download.



