This chapter introduces Drupal's built-in performance features. It explains how Drupal's built-in page cache works, and details how it can be configured. The chapter also discusses Drupal's built-in CSS and JS aggregation and compression. The importance of regularly purging Drupal's logs will be discussed. And finally, the chapter will explore Drupal's throttle module.
There are many things you can do to improve the performance and scalability of a Drupal powered website. Before adding or upgrading servers, applying performance oriented patches, or any of the many other topics of varying complexity that will be discussed in this book, you should first enable all of Drupal's relevant built-in performance options. Find Drupal's performance configuration options by navigating to the Performance page in the Site Configuration section of your website's administration pages.
When the page cache is enabled, Drupal will save a fully rendered copy of each page accessed by anonymous visitors in the cache_page database table. When the same page is subsequently visited by the same or another anonymous user, the pre-rendered, cached copy is quickly and efficiently served directly out of the cache_page table. As most public web pages see significantly more anonymous traffic than logged in traffic, enabling the page cache generally results in a very significant performance improvement.
Drupal's page cache only caches pages accessed by anonymous visitors utilizing the HTTP GET method.

When enabling Drupal's page cache, you can select normal mode or aggressive mode. You can also completely disable the page cache. It should be noted that the page cache is not Drupal's only cache. Disabling the page cache does not affect Drupal's other caches, such as its menu cache, form cache, or filter cache. Of all of Drupal's caches, the page cache is one of only two caches that can be manually disabled. The other is the block cache, discussed below.

The different cache levels are defined as constants in the bootstrap.inc include file. Though CACHE_DISABLED, CACHE_NORMAL, and CACHE_AGGRESSIVE are all defined, only CACHE_DISABLED and CACHE_AGGRESSIVE are directly referenced in the core Drupal code. This is because whether you have normal caching or aggressive caching enabled, the same anonymous page content is cached. We will discuss the differences between these two caching modes more thoroughly below, for now simply noting that when in aggressive caching mode, Drupal does not call the _boot() and exit() hooks in any modules.
When page caching is enabled (normal or aggressive), the first time a page is generated for an anonymous visitor the resulting output is stored in the page_cache database table. This is the result of the last line of index.php, where there is a call to the function drupal_page_footer() in common.inc. This function calls page_set_cache() in the same file, which verifies that the current page is being served to an anonymous visitor using the HTTP GET method, and that there haven't been any Drupal messages set in the current session. If these three conditions are all true, the function calls PHP's built in ob_get_contents() function to retrieve from PHP's buffers the page that Drupal has generated. This output is optionally compressed, as described below, then the function calls PHP's built in ob_end_flush() function which tells PHP to flush its page buffer and send the generated page to the remote web browser. Finally, page_set_cache() calls the Drupal function, cache_set(), storing the anonymous page in the cache_page database table.
The next time this page is visited by the same or another anonymous visitor, the cached copy that was previously generated and stored is retrieved directly from the cache_page database table, bypassing the need to regenerate the page. Logic for actually retrieving a cached page from the database lives in Drupal's bootstrap.inc file. The process starts in the first couple of lines of index.php, with a call to the drupal_bootstrap() function defined in bootstrap.inc. The bootstrap function defines a series of phases which are called one by one. The first phase initializes Drupal's configuration array, reading settings.php. In the second phase it's possible to define custom caching functions, making it possible to do things like using memcached for caching Drupal data. The third phase initializes the database. The fourth phase loads the session data, typically from the database. And finally, the fifth phase makes a call to page_get_cache() which loads the cached page from the cache_page database table. If in normal caching mode, the fifth phase executes the _boot hook in all modules defining it, then displays the page to the anonymous visitor. Finally, the _exit hook is called in all modules that define it, and Drupal exits.
Though the above logic may already sound complicated, it all happens very quickly, and allows Drupal to avoid loading and running a significant amount of code.
As noted above, when switching the cache from normal mode to aggressive mode, Drupal no longer calls the _boot and _exit hooks during the fifth bootstrap phase. This has several performance and scalability advantages. First, it means that the modules defining these hooks do not need to be loaded into memory.




