Optimization option

Events happening in the community are now at Drupal community events on www.drupal.org.
alesl's picture

Hello,

I'm currently building site and have noticed that my site is quite slow (average load time 400ms). So I was thinking of a ways to make it faster for anonymous user. I was unable to use normal caching because at least two modules (that is blocks they provide) ubercart and polls are not compatible or are less functional. One way to solve this problem is by using additional ajax request and fill block from there, but that seems to be a messy solution. So, I came to an idea, to do the same thing but without extra ajax request. Another idea was, that not every module is needed for rendering few blocks, so why should all be loaded.

Procedure can be described by these steps:
- enable normal caching
- each block (their html) has to marked by two unique comments (by slightly modifying block.tpl.php)
- in index.php some additional logic must be added:
* bootstrap drupal to DRUPAL_BOOTSTRAP_SESSION (a stage before late caching)
* stage DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE have to be duplicated with exit statement removed
* if cached page exist then
- bootstrap stages DRUPAL_BOOTSTRAP_LANGUAGE and DRUPAL_BOOTSTRAP_PATH
- load and initialize ONLY needed modules (in my case i only needed to load 25% of modules to render poll and cart blocks)
- render needed blocks
- in cached page replace just rendered block using markers from first step
- print page and exit script
* if cache does not exist then complete bootstrapping let drupal complete request unmodified

I implemented this technique and got 50% speed boost (from 2.52 req/sec to 5.51 req/sec).

So, what do you think?

Regards,
Ales

Comments

That's one way to deal with

Jonah Ellison's picture

That's one way to deal with dynamic content and "donut caching." A couple thoughts:

  1. Do not hack core. Dealing with a hacked core is always a pain. You can actually achieve the above through $conf['cache_inc']. Use a copy of the core cache.inc file if you're using the database for cache bins. Set $conf['page_cache_fastpath'] = TRUE, then implement function page_cache_fastpath() for loading the rest of the bootstrap modules, text replacements, page serving, etc.
  2. One downside is that the cached page can't be gzipped in the cache, so it always has to be compressed again when sending to the browser.
  3. That's actually over a 100% speed increase. ;)

Thanks for advice

alesl's picture

I didn't hack the core, just index.php. I was looking for a way to pack this in a module or something but found no appropriate hooks for that. Now that you tell me where to put it, I will move my logic into page_cache_fastpath. Do you know, if there is any drupal function that would tell me module dependencies?

Regards,
Ales

Edge Side Includes

mikeytown2's picture

Sounds like ESI in short; except at the PHP level. I believe this is kinda what Khalid did using memcache.
http://sf2010.drupal.org/conference/sessions/24-million-page-views-day-6...

If this does require a core hack, I'm sure it will be a very small one or khalid wouldn't be using it most likely.

No core hack ...

kbahey's picture

There was no core hack needed for this.

What it needed was a modified memcache.inc that checks for a custom function, and then executes it passing in the page HTML, and returning the modified page HTML back.

The details build on this article: Examples for Drupal custom caching: adding a cache timestamp cached pages.

Instead of the time stamp, do whatever processing you need to replace strings and such.

The kittens purred in joy for being spared ...

Drupal performance tuning, development, customization and consulting: 2bits.com, Inc..
Personal blog: Baheyeldin.com.

High performance

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: