19 simple methods to improve the page speed performance of a Drupal site
Site speed is one of the most critical factors when running a site. If a site takes too long to load, visitors will hit the back button and go elsewhere. Google is well aware of this, so slower sites will not rank as well as fast sites (all other things being equal).
Drupal performance optimisation can be a complicated specialisation in its own right. Consultants and Drupal agencies can spend days or even weeks investigating performance issues and fixing them. But there are many quick fixes and simple methods that you can implement right away. You don’t have to implement absolutely everything on this list - you can implement some and monitor the difference it makes to the site speed.
There are two great tools for monitoring the changes you make - YSlow and GTmetrix. Make a record of the key metrics (page load time, page size, number of HTTP requests and the overall speed grade) before you make each change and then afterwards, noting the difference to ensure you are moving in the right direction. You can also try tools like JMeter and Apache Bench.
Core caching and aggregation
Turn on core page caching
It might sound obvious to enable the default caching, but a lot of people miss this. This caches the entire rendered page in the cache table. So when each page is served, it is served from just the single cache table without all of the numerous queries being run. This is a significant performance boost. This only works for anonymous (non-logged in) users because pages for logged in users is dynamic and can be different for each user, so caching the entire page is a lot more difficult.
You can enable page caching in the core performance settings page, which can be found under Configuration -> Performance (admin/config/development/performance).
Turn on core block caching
While page caching caches entire pages, block caching caches individual blocks. This is useful for two reasons: 1) blocks will be cached if you have page caching turned off and 2) even if you have page caching on, it will not work for authenticated (logged in) users, so block caching will represent a performance boost for them.
You can enable page caching in the core performance settings page, which can be found under Configuration -> Performance (admin/config/development/performance).
Enable built in CSS and JS aggregation
In the same admin form as the default caching, you can enable CSS and JS aggregation. If aggregation is left off, there will be many CSS and Javascript files. Each one represents a separate HTTP request and having that many requests can slow page loads down. Enabling aggregation converts all of the many CSS and Javascript files into just a few files, reducing the HTTP requests by a lot.
You can enable page caching in the core performance settings page, which can be found under Configuration -> Performance (admin/config/development/performance).
Views caching
Enable Views caching
Views is the most popular Drupal contributed module (and will be in core in Drupal 8) and is used on most sites.
Without caching, every time a user requests a page with a View on it, a database query is done. These database queries can add a lot of time to page loads. If you enable Views cache, the result is stored in the Views cache table and that is used for the duration of the cache, rather than the query being run every time.
Views caching is great for logged in users (authenticated) because the output of the View is still cached even if the rest of the page is not.
Enable Views Content Cache
The downside of Views caching is that results are not real time. If you set the cache time for 10 min, the results will be the same for the next 10 min. If the content returned from a View changes, a new cached version of that View is not triggered. You simply have to wait for the full 10 minutes.
Views Content Cache fixes this problem. It will monitor the content that the View is returning and clear the cache if that content changes.
To use it, after enabling the module, go to basic settings for the View. Under Page: Caching options, select the events that you’d like to use to update the View.
Enable Views block cache
Drupal has built-in block caching. Blocks that are generated from Views are excluded by default, but can be included with Views Block Caching.
For a given View, head to the advanced settings. At the bottom, you should see Block caching. You will choose to either cache the views block once or more granularly such as per page, per role, per user.
Enable Views Litepager
If you have the default pager or Mini Pager enabled on views, COUNT queries need to be executed for first, page number and last. This adds extra processing time and is especially expensive when using MySQL’s InnoDB engine (InnoDB is recommended for high traffic sites).
Views Litepager removes the need for these COUNT queries by displaying only the previous and next links. You lose some functionality, but you gain in page speeds.
Flat HTML files
Enable Boost
Boost turns all Drupal pages into flat HTML files and stores them in a cache folder. When a user visit the page, the server returns the cached file from disk and there is no PHP and MySQL processing. This makes a huge difference to page speeds. Boost is especially good for smaller sites on shared hosting where Varnish (Varnish caches pages to memory instead of the file system and is even faster) is not an option. Boost works for anonymous users, but users that are logged in (authenticated) will still get normal Drupal pages.
Faster 404 errors
Enable Fast 404
Page speeds will be significantly slower if your site has broken images or CSS file paths. Drupal will still attempt to load these paths for every page in which they are included but they will return a 404 error (page not found). Drupal will do a full bootstrap when serving a 404, so this consumes a lot of resources.
The Fast 404 module changes the way 404 errors are handled, delivering fast 404 error messages.
Disable bad core modules
Uninstall the Statistics module
The Statistics module collects similar data to Google Analytics such as how many times content is viewed. This adds multiple database writes per page load.
It is recommended that you use Google Analytics (or a similar analytics system) instead to save these database writes. You can use the Google Analytics Reports module to such the Google Analytics data in so you can still view it within the Drupal interface.
Disable PHP Filter
The PHP Filter module allows you to use a PHP text format. This means that you can store PHP in the database and run it on page load. This is both a security problem and a performance problem and should never be done. All code should be in modules, not in the database.
To remove it, simply disable the PHP Filter module. Don’t delete the module itself though, because it is a core module.
Disable Update Manager
The Update Manager polls Drupal.org to check for modules that are out of date and ready for an update to be applied. While it is essential that you know which modules need updating, it does add load to the server to check.
If you have a staging or dev site, you could run update manager there instead of your live site.
Reducing the number of modules
Limit the number of modules in use
Every module you have installed and enabled will add to the page execution time. So don’t just install every module you think you might need - really think about what modules you actually need.
In many cases, it is better to create a custom module to do exactly what you need than it is to install a large module and only use 10% of its functionality. This is especially true if you find you're having to use multiple modules together to get your desired functionality.
Disable and uninstall unused modules
You (or your developers) might remove modules without disabling them first. This means that they are still enabled in the database even though they are missing from the file system. This can have a huge negative impact on performance.
You can find these modules using Clean Missing Modules or Missing Module and then disable them.
Images
Resize images
Images with large file sizes take a long time to load. Wherever possible, you should resize images so they are not larger than they need to be.
For image fields, you can use image styles (admin/config/media/image-styles) to resize images to the desired size.
The Image Resize Filter makes this a lot easier for inline images that are inserted via a WYSIWYG editor like tinyMCE or CKeditor. If you set the height and width of an image, Image Resize Filter will automatically resize it to match.
Install ImageAPI Optimise
Even when using image styles (ImageCache in Drupal 6) and Image Resize Filter to scale images down to the correct size, images still contain data that slow down load times. The ImageAPI Optimise module removes this data without affecting the quality of the image.
The ImageAPI Optimise module does require certain utilities to be installed on your server. If you don’t have access to your server, you can use Yahoo’s Smush.it, which you can select in the settings.
Advanced caching
Install Entity Cache
Content, users, taxonomy terms are all Entities in Drupal 7. Most entities have fields and when each entity is loaded, queries are performed to load the fields to. The end result is a lot of queries!
Entity Cache helps address this by caching the fully loaded entities into a cache table. Each loaded entity is a row in the cache table.
Using this module is as simple as it comes. Just enable it. No configuration required.
A word of caution. I have seen significant performance improvements on complex sites with large sets of fields, Field Collections etc. Your mileage might not be as great if you have a simple site. Also, I have found that there is an incompatibility between Ubercart Price Per Role and Entity Cache.
Install Advanced CSS/JS Aggregation
While built in core CSS and Javascript aggregation does a decent enough job at reducing the number of requests that the browser needs to do by aggregating it into one file, the Advanced CSS/JS Aggregation module does this in a much more intelligent way.
Limit the number of times cron is run
Drupal 7 has a feature that allows cron to be run automatically without having to set it up on the server. The downside is that it is run when a real user hits a page. By default, it will run every 3 hours. This means that the first user to hit a page after that 3 hours will trigger cron, making the page very slow for them.
The best solution in terms of performance is to disable this and set cron on the server so that it is run in the background.
Wrapping up
This represents a run down of some of the easier solutions to boost the performance of Drupal sites. As mentioned at the top of the post, monitor the changes to be sure there is actually an improvement (there is no point in using something if it doesn’t actually help).
Let me know in the comments below if you can think of any more quick wins to improve performance of a Drupal site.