-
Dylan Tack
OpenSourcery Alumnus
I attended several sessions at Drupalcon on performance and scalability. One common thread was the need to offload static files to dedicated servers or a content delivery network (CDN). The use of a CDN is also part of the well-known YSlow test for measuring front-end performance. With CDN providers getting cheaper by the day, content delivery is not just for big media companies anymore! A bit more explanation is required to understand why this is complicated in Drupal, and what's being done about it. As a bonus — I'll share a trick for getting a useful chunk of your files on a CDN in less than 3 minutes.
With the advent of cheap, auto-magical mirroring CDNs, this should be easy right? One of the challenges is that links to files can come from several disparate Drupal subsystems:
file_create_url(), which doesn't filter links through custom_url_rewrite_outbound(). There are several approaches in the works for D7 to address this; I've worked on one of the patches, though I'm not yet sure how the reworked File API impacts this.drupal_get_css() that do their own string URL manipulations.print '<img src="' . $base_path . path_to_theme() . '/images/logo_bw.png" />' isn't uncommon.At Drupalcon, Wim Leers presented his work on the CDN Integration module, and it seemed very promising to me. There are plans to support both push and pull CDN providers, and even possibly things like video transcoding servers. However, it's neither production-ready yet, nor available for Drupal 6.
So what are we to do? To cover all these bases, we might imagine a core hack or two, an implementation of hook_filter, custom_url_rewrite_outbound, and more. But I promised you a win in three minutes, so...
/* This goes in your theme's template.php, and will modify the $styles * variable that gets passed to your page template. CSS background * images will also be pulled from your CDN. */ function mytheme_preprocess_page(&$vars, $hook) { if ($url = variable_get('cdn_url', '')) { $vars['styles'] = str_replace('href="/', 'href="' . $url, $vars['styles']); } } /* This goes in your server's settings.php, * and assumes you have a "mirror bucket" set up at this URL */ $conf = array( 'cdn_url' => 'http://mirror-e7.your-cdn-provider.net/', );
Tagged as: CDN, content delivery, Drupal, Drupalcon, performance
Nice
Nice one Dylan. Any idea if this'll work with Cloud Files CDN? We haven't signed up with them yet but I'll take your code out for a spin once we've got an account.
Thanks for the article
Thanks for the article
Cloud Files CDN?
Tanc,
After glancing at the Mosso page you linked to, it wasn't clear to me if they're offering the kind of mirroring service you'd need for this particular technique to work. I'm using SimpleCDN; the mirror means that requests for objects not currently in your bucket will be automatically mirrored from your server.
The Mosso folks did have a booth at Drupalcon, so I'm sure they have solutions that work with Drupal.
Even though abusing the theme
Even though abusing the theme layer is fun and all, it isn't strictly necessary in this particular case, since any module can implement a preprocess_page function. That way the use of the CDN can remain theme-independent.
mod_cdn
Another easy win is img tags. You can use mod_cdn to autoreplace the URLs in image tags to use the domain of your CDN.