How do you dramatically cut the load of code going into Drupal? Use the code load cut described here.
All content management systems (CMSs) are based on many chucks of code both large and small, as it is the only way of providing the wide variety of functions you need in CMSs. Drupal, like other well designed CMSs, lets you switch on only the chunks you need which reduces the code load.
There are lots of options in Drupal and many are used for Web sites from the largest to the smallest. The resultant code load is based on the options used, not the size of the Web site. If you have a relatively small site and the page load times are slow, it is probably your Web site host not allocating enough resources and you can take steps to reduce your resource usage, including cutting the code load.
PHP Accelerators
Drupal is based on PHP code because PHP is optimised for the Web and PHP can be further optimised by using products commonly known as PHP accelerators. One PHP accelerator is named PHP Accelerator while another is named the Zend Optimiser. The accelerators use a technique used for many years on many languages, which is to compile the code into memory then save a copy of the compiled code before using the code. Subsequent uses of the code can just load the compiled version, not the original.
Accelerators save space by throwing away comments and compressing the remaining code. When you choose to use Drupal modules containing lots of comments, you know the comments will not slow you down.
Administration Overhead
The remaining accelerated code can still be a big load because of all the strings of text and complex code, particularly in the administration area. The strange thing is, Drupal (and most other CMSs), load all the code all the time, even administration code that may be used only for a few minutes per day by one person. In some Drupal modules, the administration code is 80 percent or more of the total module code, which means the module loads five times too much code for every single Web page.
A really nice trick would be to move the administration code out to a separate chunk that is loaded only when needed.
Module Load Code
Modules are managed by code named module.inc in the Drupal includes directory, and loaded by function drupal_load() in bootstrap.inc, also in the includes directory. If we could modify drupal_load() to automatically load administration code then we could separate out the administration code.
*.admin.inc
We need a standard name for the file containing the administration code, one that fits in with current Drupal file names. Drupal modules are named *.module and included files are named *.inc with the *.inc files protected from public view. A module named Example is in a directory named example and contains a code file named example.module. If module Example has an optional include file then the include file is named example.inc. We could simply add a file named *.admin.inc, example.admin.inc in our example module, and look for the *.admin.inc file when we are in the administration area.
drupal_load()
drupal_load() loads the *.module files. We could then add code to load *.admin.inc when needed. Look in includes/bootstrap.inc for drupal_load() and familiarise yourself with the code.
I do not recommend you make any of the changes mentioned here as the changes may destroy your Web site and produce all sorts of related problems that I cannot predict for your site. I am only telling you what I do on my site so that someone can use this idea to improve your site.
I can perform the change on your site for a fee and most other Web developers are cheaper. This minor change to drupal_load() takes very little time and the real effort is improving individual modules.
Look in drupal_load() for the following code. $type contains 'module' and $name contains the module name, such as 'example'. drupal_get_filename() returns the file name for the module named example and the include_once statement brings the module file, example.module, into Drupal.
$filename = drupal_get_filename($type, $name);
if ($filename) {
include_once "./$filename";
$files[$type][$name] = TRUE;
return TRUE;
}
I expanded the code in several ways. First I changed the format of the code to a more modern readable form. The next change expands the include_once to correctly pick up the file no matter how your directory is structured. Finally I added the code to check for admin files.
The if() statement, in the following code, checks for a type of 'module' so we can check for admin code only when loading a module and the second check, of the filename, is there because the first check produced an occasional stray load of the admin code that I did not bother tracking down. $location is extracted from the request path to see if the first part of the path contains 'admin'. We then check if the admin file exists and load the file if it exists.
if($filename)
{
include_once drupal_document_root() . $filename;
if($type == 'module' and substr($filename, -7) == '.module')
{
$location = reset(explode('/', $_GET['q']));
$admin = 'admin';
$admin_file = drupal_document_root() . substr($filename, 0, -7)
. '.' . $admin . '.inc';
if($location == $admin and file_exists($admin_file))
{
include_once $admin_file;
}
}
$files[$type][$name] = TRUE;
return TRUE;
}
Test the change thoroughly before using the change on an important site. If you contribute to Drupal code then you might be able to talk the Drupal developers into making this small change a standard feature.
Change a Module
Analyse the Impact
Some modules have no admin code which means you do not need an admin.inc file. Some modules have such small admin code sections that it is not worth the work to change a module. Focus on the modules with the greatest gains.
For modules with small gains, change them only when you are performing other work on the modules. You will have to maintain the changes until the technique is picked up by Drupal and there is no point chaning a module for a very small gain if you are not otherwise changing a module. Once you make any change to a module, the extra work for the admin split is trivial.
Use the statistics module for your practice run. I divided the 23 KB statistics.module into a 12 KB statistics.module, including some additional documentation, and a 16 KB statistics.admin.inc, including some additional documentation.
Create the Admin File
You can create the statistics.admin.inc file using your favourite editor or just copy another .inc file, rename the copy, and delete all the contents within the opening and closing PHP elements. Note that Drupal follows the weird practice of not using a closing PHP element but PHP accepts the files anyway. I edit PHP files using an editor that understands PHP, highlights some common typing errors, and I add the closing element.
Add some documentation to describe your change. Include the date. You may need to copy the change across several releases of Drupal until Drupal adopts a similar approach.
You can now cut functions out of statistics.module and place them in statistics.admin.inc based on where the functions are used. Function statistics_access_log() is only used from path admin/logs/access which means the function will only be used when statistics.admin.inc is loaded.
The functions in my statistics.admin.inc include statistics_recent_hits(), statistics_top_pages(), statistics_top_visitors(), statistics_get_host_by_address(), statistics_top_referrers(), and statistics_access_logging_settings().
Split the Menu Function
You could split the statistics_menu() function into two parts, one in statistics.module and one in statistics.admin.inc, but the split technique is a little more complicated than just moving functions. I do not recommend this part of the split until you have completely tested the previous changes.
statistics_menu() starts by setting $items to an array. You add code to test for a location of admin and include the function named statistics_menu_admin. You will add statistics_menu_admin() to statistics.admin.inc and the function will return an array populated with menu entries.
$items = array();
if(reset(explode('/', $_REQUEST['q'])) == 'admin')
{
$items = statistics_menu_admin($may_cache);
}
statistics_menu_admin() accepts the $may_cache parameter and sets up menu entries in the same way as statistics_menu(). look at all the menu items with paths starting as 'admin/'. They can all go across to statistics_menu_admin().
I know this part of the explanation is light on detail but you should only tackle this part of the code split when experienced enough to understand the Drupal menu system.
Conclusion
If every Drupal module was analysed for the admin code cut and the biggest gains implemented, Drupal would create less load on our Web servers, particularly the smaller sites on virtual hosting and VPSs where memory can be tight. The code cut is easy to implement and a great long term gain for Drupal. The splitting of large modules into two smaller code chunks also makes module development easier and more organised.









- Facebook Like
- Google Plus One
- Log in or register to post comments