For what it's worth...here is how to GREATLY speed up your home page display!

Permalink
I am working on a much broader solution to speeding up a concrete5 site and still have a ways to go but in the meantime...here is how to GREATLY speed up the display of the home page.

Nothing fancy about this method but I have not seen it described on the forum anywhere so I thought I would post about it for what it's worth.

A couple of caveats first...

The approach I mention here will serve up an HTML static version of the home page. As such you must have an index.html file in the root directory of your domain that corresponds to that version of the home page served up normally by Concrete5.

If you change the home page at all you will have to recreate the HTML version of the home page and upload it again.

This approach is also for people who are comfortable fiddling around with php, apache, and the like and is --NOT-- really intended for end user clients who would as likely be totally lost as to how to change things here and there than not.

Now on to the method...

- traverse to your home page in a browser
- enter Ctrl+U or whatever keys you must press to view the source code of the page appearing on your screen.
- copy that code and place it into a file called index.html
- upload to the server root of your domain
- add the following line to your .htaccess file

RewriteRule ^$     index.html [last]


Now that line has to be added at a specific place in the .htaccess file.

Here is an expanded .htaccess file with liberal comments to show you where to place it.

# -- concrete5 urls start --
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# MUST be placed before the RewriteCond statements below to keep from becoming an endless loop
# If request is just the base domain name and nothing else rewrite the URL to point to index.html and don't execute any further
# rewrite rules
RewriteRule ^$     index.html [last]
# REQUEST_FILENAME is a mod_rewrite variable (as opposed to a normal server variable).  It contains the full local
# filesystem path to the file/script matching the request, if this has already been determined by the server at the time
# REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI.
# You can get more info about this variable at:http://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteCo...
# The "!" character negates the pattern string used ("-f" to indicate a file and "-d" to indicate a directory).  So !-f is true
# if requested resource (as found in REQUEST_FILENAME) is a file that does not exist.
# Condition is met if requested resource is a file name that does not exist


You should view the above code by clicking on the View complete code link just below the code and to the right.

The above causes the home page to be displayed lighting fast.

I am working on an overall solution to serve up static versions of pages unless the date of the last revision in the MySQL C5 database of a page is later than the date of such static versions (in which case the regular C5 rendering and display will occur) but I am not there yet.

Thought someone might find this useful or that it might give someone ideas.

I've tested the above on several sites that use Concrete5 and it is working as I have described (but you use this approach at your own risk). The speed difference is huge.

For what it's worth.

Carlos

 
boomgraphics replied on at Permalink Reply
boomgraphics
I am curious why this method is faster than say, C5's full page cache?
carlos123 replied on at Permalink Reply
A couple of things...

I am no expert on caching (yet :)) but from what I understand (if anyone reading this sees a wrong understanding on my part please correct me)...

C5's cache is broken first and foremost. There are threads on here, very, very long threads where this is discussed. So for now it is actually faster to turn off C5's cache.

Until that is fixed we need another solution.

I confess I do not understand the caching mechanics used by C5. As to whether it is server based or relies on Expires HTTP header instructions to the client browser to do caching or some such.

The problem with browser based caching is that such does not improve first visit, page loading in that the browser has to first receive a page's elements before it can...well...cache them.

Another problem with browser based caching is that even when cached...it is relatively difficult to force the browser to serve up a fresh page. For example how does one tell a browser cache to serve up a fresh version of a page that has changed if the Expires HTTP header instructions previously sent told it to not serve up a fresh page until way into the future?

The only way I know how is to change the Expires HTTP header (necessitating a change in the .htaccess file) or to add some validator string to the name of the resource that essentially fools the browser into believing that the resource is new.

Which is a pain in that such headers often are aimed at all html files, at all images, and do not target one specific resource (i.e. file) that has changed.

Which again means more fiddling around inside the .htaccess file to force the browser to retrieve and serve up a fresh page.

Storing the files as static html files on the server and serving those up instead avoids all that fiddling around with Expires or similar headers.

If C5's caching mechanism is server based it definitely is the way to go but as I said...it's broken right now.

I want speed now not when the next C5 update comes around :)

Hope that answers your question.

Carlos
carlos123 replied on at Permalink Reply
I just found out something interesting.

C5's cache is based on Zend's caching mechanism. Zend's cache does not actually store a static version or copy of the file produced by PHP scripts like those of C5.

Instead it pre-compiles (though this is a misnomer in that PHP is not a compiled language) portions of the PHP scripts used (as part of what it does to speed things up).

In other words the PHP script still runs under Zend cache only it runs much faster is all.

Creating true static copies of that which renders on the screen and serving up those static copies to site visitors should be faster than even Zend cache (or C5's cache) in that serving up static files is about as fast as you can get. No PHP script is run at all.

No database access.
No PHP script is run.
Very little of C5's PHP init code is run if it is run at all.

My goal is to completely bypass C5 altogether and use it mainly to edit and modify a site. But once a page is modified and in a state where it is likely to remain so I will create a static version of that page and serve it up instead.

In theory such an approach could completely invalidate the need to use C5 at all once a site is pretty much where you want it and where you don't foresee having to make any changes for some time.

Where you could just blow C5 away (and it's overhead) and simply serve up static pages only.

That's as fast as it gets I think.

All the benefit of C5 as a content management system and all the benefit of static site (i.e. SPEED)!

Carlos
andrew replied on at Permalink Reply
andrew
There are some bits of truth to what carlos123 is saying. concrete5's cache attempts to cache as much as it can without leading to those "what the heck is going on?" scenarios that caching so often leads to. This means keeping track of what types of content are cacheable, etc... I always find caching to be faster, but Zend_Cache's file-based cache does lead to a lot of IO on certain servers. Additionally, in versions of concrete5 prior to the current one in github, the cache lifetime was set to fairly short on certain bits of content, which could slow things down.

Full page caching is an extension of this basic caching. It is not as simple as writing an .html file to a directory, however. Much of the concrete5 libraries are still loaded, including the beefy Zend libraries. If you have statistics disabled and full page caching enabled, however, you won't connect to the database to display content, so that will definitely help. It will be a bit slower than just writing out an .html page and redirecting to it, however. Of course, as you can see further down thread, there are problems with this approach. Full page caching is transparent, works within concrete5, can be turned on selectively through the GUI, and honors sitewide cache settings.
carlos123 replied on at Permalink Reply
Hmmm...there is a problem with doing things this way so it might be advisable that it not be used just yet.

You cannot log in to the C5 admin interface!

Apparently it's an Apache thing in that I added an index.html as the static version of the home page served up by index.php (the C5 file).

Even when removing the line I proposed into the .htaccess file Apache will still serve up index.html before it processes index.php so any index.html file in the domain root directory will continue to be served up until it is deleted or renamed to something other than index.html.

Resulting in an inability to log in since Apache will always load index.html first.

The solution is simply to delete the index.html file or rename it.

Not a big deal but I will have to come up some some other way to have the home page served up than by calling it index.html :)

The speed difference is quite HUGE though so it's worth it for me to continue working around the broken C5 cache for now I think. Besides I am learning lots about caching.

If anyone has any suggestions let me know.

Thanks.

Carlos
jshannon replied on at Permalink Reply
jshannon
I've been thinking a lot about this ever since I found an (old) post in the forum's that talked about wordpress' "super cache", which, I would guess, does what you're proposing(albeit better thought out. :) ).

mod_rewrite is incredibly powerful, though I'm the first to admit I can't wield the power effectively.

What I was thinking, and the direction you were going in, would be:

if (there's a CONCRETE5 cookie (AFAIK this is only set when the user is logged in)) {
    run index.php as usual
} else if (a file exists by the name of [request].html, where, if [request] is blank, it's replaced with index) {
   return file
} else {
  run index.php as usual 
}


And you'd make concrete in charge of saving the .html file if a flag isn't set (that way pages like login would always be "live").

Also, I believe c5 does more than pre "compilation". I believe it does something like the above where it saves snippets of html output, like for blocks, but it still requires, at the least, dispatch.php to run, include about 20 files, and connect to the database.

James
carlos123 replied on at Permalink Reply
I fixed the problem!

I set up a directory in the domain root calling it mycache.

I copied the source generated by C5 when visiting the home page into a file called home.html (could have called it anything really other than index.html).

And I replaced a line in the .htaccess file (the only line I added to the .htaccess file in my original post other than the comments) to read...

RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{DOCUMENT_ROOT}/mycache/home.html -f
RewriteRule ^/*$ mycache/home.html [last]


Basically this runs the RewriteRule only if the request is a GET and only if the file in question (home.html) exists in the mycache directory.

This now serves up the home.html static file while also allowing me to log in to the C5 admin interface like normal.

I have not yet implemented logic to test for a new version of a page inside the C5 database so this approach serves up the static version of a page (the home page in this case) indefinitely but one step at a time.

Back to super fast first page load of at least the home page! Yippee!

Carlos
carlos123 replied on at Permalink Reply
Thanks for the additional input Andrew and Jshannon!! Good stuff.

This is exciting to me and mirrors something I was setting up when I was creating my very own CMS. Where users could completely bypass the CMS entirely and run a static version of their site using source code produced by the CMS instead of having the CMS be in charge of serving up pages.

I'll keep working this out into C5 as I have time but in view of the significant speed benefits gained...it's well worth my making time for this.

C5 is a great CMS but in all frankness it's just way too slow compared to what I am used to not only using my own CMS but also even that of WordPress, TextPattern, and the like.

Carlos
mesuva replied on at Permalink Reply
mesuva
I did implement a static html style caching a little while back. I've had quite a lot of success with it on a couple of sites. I've used it on this site for example -http://www.saba.org.au/ . With this caching on, it is pretty zippy and the homepage loads almost instantly. With it off, it is ok, but significantly slower.

This system basically just serves static files, clearing the cache when edits are made.

http://www.mesuva.com.au/blog/technical-notes/an-extra-cache-for-co...
carlos123 replied on at Permalink Reply
Hi mesuva,

Thanks for letting me know about your cache. I looked at that somewhere else...I can't remember where and even downloaded and looked at the code but...it was way too complicated for my purposes.

Couldn't understand half of what your code does and even trying to follow your info on the link you posted here is difficult. That's no fault of your own necessarily mesuva. It may just be the nature of what you are doing with your cache.

What I have in mind to do is create an Add On that ties into the C5 interface. A user goes to the Add On config page (within the C5 interface) and just puts checkmarks next to the site pages that they want to create as static files. Then they press a button to generate the static versions (pressing that button also modifies the .htaccess file automatically under PHP control).

I'd probably use wget to fetch those files internally in my code and save them to static html files.

From that point on those files are what get served up until they uncheck that file from the Add On configuration screen and click the regenerate button again.

I might tie something into the Publish update button action that C5 uses to have a user indicate that they want their changes implemented on a particular page such that when they publish their change by pressing the button that particular page is created as a static page and used instead.

I just need to figure out where to read a list of page url's from within C5 (i.e. those files that show up in the sitemap that are on the menu) and where the publish changes (or whatever it's called) button does it's processing so that I can change the code and add to it.

I guess what I am saying is that the ideal cache that I have in mind is very, very simple. Such that anyone could implement it without much of any fiddling or even knowledge of what is happening other than that there are static files and pages created by C5 on the fly with their choice limited to one or the other.

Carlos
mesuva replied on at Permalink Reply
mesuva
Hey Carlos,

I like what you are suggesting with it being controllable from the C5 interface. It's actually something I wouldn't mind doing with my cache idea, since it's easy to let it know what pages to cache or exclude. I'd probably just have it an extra dashboard page though.

With my cache system, maybe I've not indicated how simple it actually is. It is supposed to be very passive, only coming into play when it is safe to do so. I've had others use the system without any issues.

There are only two steps you need to do.
- One is to copy a folder from the zip into the libraries folder.
- The other is to replace the dispatcher.php file in the concrete folder with the one included in the zip.
That's it. It's no harder than installing a plugin. In fact, there are less steps!

At that point it should be working. The extra stuff on the page is about further configuration, how to turn on debugging, etc. Only really the first two lines are useful anyway.
carlos123 replied on at Permalink Reply
Hi Mesuva,

Before I read your new response I read through the code of your cache again (or presumably again). I am not entirely certain that I actually ever read your code to begin with and may have mistook what I did look through before with yours...because...well...there is really nothing difficult to understand in your code mesuva. It's pretty self explanatory with good comments thrown in.

Sorry about that.

It does look simple now that I have actually taken a look at it.

I might play around with it to learn from what you have done.

Good work!

Carlos
mesuva replied on at Permalink Reply
mesuva
No problems at all!

I guess there are so many different ways of caching, it's hard to know what approach to take.

It's a tricky balance between serving cached pages, while having sites still be dynamic in a sense. My approach turns off caching for things like GET and POST to allow things like search forms to work. It's really just for sites that COULD be static html.. but still having the C5 editing goodness available.

It might also be something that is useful if a site got hit with large amounts of traffic, basically turning it into a static html site, with no pretty much no C5 overhead.

It's definitely not perfect though, hence why I'm trying to get some more feedback!
Let me know if you have any questions or suggestions.
carlos123 replied on at Permalink Reply
I am still having a problem logging in to the C5 interface. I thought I had the problem licked but turns out..I don't.

If anyone has any tips or insight into what the problem is and might be willing to share what they know about it...it'd be great to hear from you.

I'll get it but it might take me more time than if someone more familiar with the C5 code was to take a stab at sharing what the problem might be.

If I add the following to the .htaccess file...

RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{DOCUMENT_ROOT}/mycache/home.html -f
RewriteRule ^/*$ mycache/home.html [last]


When I try and login by going to the domainname.com/login url I am simply returned to the static home.html page as indicated above.

I mean the login screen appears but when I sign in with the proper credentials the home.html page appears and I never enter the C5 interface.

Like I said...I am tracking the problem through backtraces and the like and will get it but if anyone has any ideas please let me know.

Thanks.

Carlos
carlos123 replied on at Permalink Reply
Okay...fixed again.

The .htaccess lines above were just fine.

The problem was due to my having added a debug print line just above the call to include dispatcher.php inside index.php.

That line was output before the DOCTYPE and was not allowing the C5 interface bar to appear. Removed the line and it works fine again.

I can login just fine. If home.html exists it is displayed instead of the home page version created by C5. If home.html does not exist...the regular home page created by C5 through index.html appears on the browser.

Carlos