
A free CMS is always a compromise, a compromise between a number of obvious factors, which, it seems, it makes no sense to list which within this resource. they are all known for a long time. Of course, among the whole variety of free CMS, some can be distinguished that will be better or worse in some separate nominations, such as work speed, ease of mastering by a beginner, etc. But this article is not about that. I just want to share the experience of successfully solving the problem of page generation speed in Joomla using caching. And caching is very radical, at the “level” index.php.
I want to immediately note that this story is not some fundamental innovation, and I do not claim any laurels. I hope my decision will help at least someone to extend the “little blood” life of the old project on Joomla.
')
I just want to preempt the criticism and ask for some indulgence. The fact is that I am not a professional programmer in any way. I am the technical director of a small printing house. All my programming efforts are just efforts to reduce IT costs in a company.
As it seems to me, quite typical (in any case, among amateur programmers, whom I consider myself to be) is the following situation. At one time, when I started writing a website for myself, I chose Joomla, because it was an obvious, though not very far-sighted, decision. Over time, I encountered some limitations of Joomla, one of which was the time of page generation.
For those who are in the subject, it's probably not a secret that due to the load of a heavyweight framework, plug-ins and modules, well, as a payment for the versatility of CMS as a whole, the typical page generation time can be about 1-2 seconds. The use of more powerful hardware does not solve the problem, because if a CMS makes several dozen (or even a hundred) requests to the database for one request, an increase in the productivity of iron (and all its components) will be required by an order of magnitude, which is very expensive, to say the least.
I must say that joomla 1.5 itself also knows something in terms of caching. To my shame, I do not remember exactly what, because a long time to delve into it. But I do remember exactly that there is almost no sense in this caching.
The first attempt to optimize and accelerate was writing a crutch for caching the Joomla component Virtuemart. Virtuemart is a well-known (we can say "classics of the genre") component of the online store for Joomla. Of course, you can say a lot of unflattering words about him and read, because it has a lot of flaws dictated by a number of reasons, ranging from respectable age, the absence of any refactorings there, ending with openness and versatility, which, as a rule, go alongside cumbersome. Nevertheless, it (Virtuemart) is there, it works, and for many it is a simple entry point into the “world of electronic business”, so to speak. And in general, I would like to focus not on how to “properly cook” Joomla, which components and how to use. On the contrary, I would like to share a recipe for what to do if it is already cooked incorrectly. A solution that can be briefly described as “Don't touch anything, don't change anything, just make it faster so that it works faster!”
In my case, Virtuemart is used in directory mode, which somewhat simplified the task of writing a caching crutch. Describe how I did it makes no sense, because the resulting increase did not significantly affect the download speed. After all, in my Joomla there are more components that love resources, for example JoomFish. In addition, in order for Virtuemart to give up its cache, you need to load the entire Joomla framework all the time, which in itself takes time.
I started looking for a solution to speed up the download. The situation was aggravated by problems on the virtual hosting, where my neighbors had archineoptimal websites, and therefore the server was very loaded and the generation time sometimes reached 10-20 seconds.
Upon reflection, I came to the conclusion that no joomla optimization, at least within reasonable aisles — after which joomla will remain a joomla, will not accelerate at times, and this is the goal that stood before me. Therefore, it was decided to consider the writing of the frontend. I immediately dropped it and did not consider options with ready-made solutions (I don’t even know if there are any), since He had neither desire nor time. In addition, my copy of joomla is decently finished in places and typical (typical for Joomla) solutions are not the fact that they would work out of the box.
What happened as a result:
- caching almost all pages of the site in the mode of an unauthorized user
- generation speed of the order of 100-200 ms
- The minimum number of database accesses when returning a page from the cache is 1-2 pieces, more if there are dynamic (or periodically updated, with less than the page itself, TTL modules) on the pages
- integration into the mechanism of joomla sessions without launching the joomla framework itself, thanks to which all asynchronous bells and whistles work correctly within the cached pages, since when receiving a POST or GET from a user walking (without a single framework load) on the site's cache, joomla sees his session in his database and everything works as it should. At least, the standard AJAX components JComments and ProofReader have wonderfully earned me, and I also made a couple of self-written AJAX components.
Consider the implementation
- In my case, I placed all the frontend in the index.php file, because it is in it that the generation begins and ends.
- First of all, we analyze the URL to determine if it is allowed to cache this page. In my case, joomla uses the SEF link generation module, which replaces links on almost all pages of the site with cyrillic ones. So in my case, all links in which are /index.php are forbidden for caching.
$fe_disalolwed_urls_array = array(
"/index"
);
.........................
if (fe_check_url($fe_disalolwed_urls_array,$fe_uri_cp1251)) {}
.........................
function fe_check_url($a, $i)
{
foreach ($a as $aa)
{
if (substr($i,0,strlen($aa)) == $aa)
{
return false;
}
}
return true;
}
This operation does not require access to the database, everything happens in the index.php file.
If page caching is forbidden, we leave for the regular generation of the page with loading the framework, etc. etc.
- We also check the presence in the request of a special cookie that joomla puts users who have passed authorization with a bird to “remember me”. This cookie has a name that is defined as md5 ('_ secret_JLOGIN_REMEMBER'), where _secret_ is a random string generated when installing an instance of joomla, you can find this string in the admin panel.
If we find such a cookie, we also transfer the control to the “great and terrible” - let it try to determine for the rest of the encrypted cookies who it should “remember”.
This operation also does not require access to the database and the file system, we are still in index.php.
- If we're still here, move on. Create a dummy session with the same name as joomla does, namely md5 (md5 ('_ secret_site')) and check if there is such a session with such an id in the josly jumla table, and if there is - whether this session is a session of an authorized user . Also in this place it is necessary to remove outdated sessions from the database, although this is not necessary - joomla itself can take care of this when some of the queries launch it.
Please note that this is the first call to the database.
Based on the results of the check, we decide what to do next. If there is no such session (and also if there is such a session and it does not belong to the registered user), we proceed to the next item, where we will determine the ability to read the page from the cache. If the session belongs to a registered user, we “leave” for the standard generation. In principle, in this place it would be possible to “dig” further - to cache pages for authorized users, but I didn’t go into this, because The specifics of my site are such that unregistered users constitute a heavy proportion of visits, despite the fact that the size of the frontend that would cache pages of registered users would increase significantly. In addition, at the moment, we have moved to new hosting, where the generation time, even without a cache, is quite stable.
- Now you need to determine if there is a cached version of this page. If it is, then we give the cache, if it is not there, then we do the generation, save the result to the cache and give it to the client. In the case of generation, you need to remember to delete the session, since joomla herself will create it!
Also, if there is no “giving up the cache” and there is no session with that name in joomla, it is important to add the session to the joomla session table. This is necessary to ensure the correct operation of joomla itself, if the user goes from cached to non-cached, for work of AJAX modules, etc. In addition, you need to perform cache processing for dynamic modules before sending to the client, see below.
In this place there are a number of nuances associated with dynamic modules.
In my case these are the following modules:
- number of users on the site in the last hour
- latest site news
- production news (this module displays the latest developments in office ERP)
- a module that displays a random user joomla (in this case, a photo of a random employee of the company is displayed)
- joomla authorization, which is static in itself, but has Spoof-protection (in the case of using the Community Builder component, the fe_cbSpoofString function is responsible for this - we are looking for the source code in joomla)
To ensure their correct operation, the following was done:
- when starting the generation of joomla, which is to be placed in the cache, we do some define
- in the generation code of the mentioned modules, if we see this define, instead of the module body, we output some magic word in the response body
- in the frontend we write (using Ctrl-C, Ctrl-V and a small file) functions that generate the text of the modules without loading the framework
- the result of the generation (in which instead of the modules there are magic words) we put in the cache
- when returning content from the cache, we change with the banal str_replace () our magic words to the results of the functions we have defined
Actually that's all. As a result, I received an acceleration of almost an order of magnitude (almost ten times).
Results trackerPhysically hosting is in Kiev, 99% of the target audience there.
You can estimate the speed of the site on it:
linkIn the picture below - a screen from Google Webmasters Tools

The February spike was caused by one problem, for which I had to delete the entire cache of the frontend every 2-3 days during the whole month. But this problem itself had no relation to the frontend.
The front end cache is cleared from the joomla admin panel; to do this, I didn’t have to do anything, except to add the cache itself to the daddy / cache / FrontEnd - joomla saw it itself and provided an opportunity to clear it ...
PS: I am sure that this approach can be applied not only within Joomla 1.5 and not only within Joomla. Of course, this will require some skills, but, at the same time, it can expand the scope of easy-to-learn free CMS.
Thanks for attention.