Load first page faster

General questions about CMSimple
bca
Posts: 293
Joined: Tue Sep 15, 2009 4:49 pm

Load first page faster

Post by bca » Wed May 25, 2016 1:51 pm

Hi
I have been doing some experiments with my site.
Using XH167 the homepage was taking a while to load - over 10 tests the average time to load was 11 seconds. I cleared the browser cache each time.
On google pagespeed it was ranked as 67/100

Following all the guidelines on google's site I created the first page from the page source as a plain html file.
In the HEAD I removed

Code: Select all

<link rel="stylesheet" href="./templates/newhomepage/stylesheet.css" type="text/css">
<script type="text/javascript" src="./plugins/jquery/lib/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="./plugins/jquery/lib/migrate/jquery-migrate-1.2.1.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
I inserted an edited template stylesheet inline.

I put

Code: Select all

<script type="text/javascript" src="./plugins/jquery/lib/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="./plugins/jquery/lib/migrate/jquery-migrate-1.2.1.min.js"></script>
at the end of the html file before the /body tag.

I named the file index.html and took out index.php.

Surprisingly it worked straight away.
The only thing I had to change was the menu links from

Code: Select all

<a href="?Contact_Us">Contact Us</a>
to

Code: Select all

<a href="/?Contact_Us">Contact Us</a>
Average page time to load was less than 1s.
Google pagespeed is now 97/100

Everything seems to work. Going back to the home page from within the site serves the original home page.

I know that if I want to edit the home page It is now more difficult.
So my question is is there an easier way of doing this?

B

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load first page faster

Post by cmb » Thu May 26, 2016 6:44 pm

Hi B!
bca wrote:Using XH167 the homepage was taking a while to load - over 10 tests the average time to load was 11 seconds. I cleared the browser cache each time.
Hm, 11 seconds seem to be very long. It might be worth investigating the reason for this (a very slow internet connection, a very slow server, some misconfiguration etc.)
bca wrote:I inserted an edited template stylesheet inline.
Actually, in my opinion, having an index.htm with an inlined stylesheet is somewhat bogus. Of course, that accelerates accessing the start page, but accessing any other page would trigger loading of the stylesheet nonetheless, and so the CSS would have to be transferred a second time.
bca wrote:I put

Code: Select all

<script type="text/javascript" src="./plugins/jquery/lib/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="./plugins/jquery/lib/migrate/jquery-migrate-1.2.1.min.js"></script>
at the end of the html file before the /body tag.
That is somewhat I would love to see as being the default, but unfortunately that would break a lot of plugins, I presume.
bca wrote:So my question is is there an easier way of doing this?
At least there is none readily available. There is a plugin called OfflineContent (or so), which creates HTML files of all pages of a CMSimple installation, but the plugin is really old, and certainly does neither inline the stylesheet nor deal with any <script> elements.

Anyhow, it appears to me that automating the index.html isn't too hard. I would probably start with mod_rewrite so that requests to the root directory are mapped to index.html or index.php, depending on whether there's a query string in the request. That might already solve the need to fix the menu links. If that wouldn't work (what I actually assume), adding a <base> element to index.html most certainly would work.

Writing the index.html could be relatively easily been done in function XH_finalCleanUp which is called at the end of each request. One of the problems would be that inside this function PHP has lost the current working directory, so this would have to be stored in a variable before the function is called, and then used. Before index.html would be written to disk, the HTML could be manipulated (inlining the stylesheet, moving <script> down etc.)

However, I would prefer a more general solution, namely a server side caching of the generated pages. That would involve PHP for each page request, but due to cmsimple/userprelude.php the real CMSimple could be skipped, if there is already the appropriate .html in the cache. One problem with this approach would be to automatically detect whether a cached file is stale. Perhaps that detection should best be ommitted, and instead the webmaster would have to clear the cache manually (or maybe the cache could be cleared on logout). There are other problems (for instance, to detect whether a request must not be cached at all, because it triggers dynamic behavior, e.g. form submission[1]). And I have no clue on how much this could improve the performance. Nonetheless, an approach that might be more carefully investigated.

[1] Theoretically, that should be easy to solve. POST requests would not be cached, but GET requests would. However, not necessarily all GET requests offered by CMSimple_XH and its plugins are safe.
Christoph M. Becker – Plugins for CMSimple_XH

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load first page faster

Post by cmb » Fri May 27, 2016 10:58 am

cmb wrote:However, I would prefer a more general solution, namely a server side caching of the generated pages. […] Nonetheless, an approach that might be more carefully investigated.
I've quickly put together a first draft. Place the following in the newly created file cmsimple/userprelude.php:

Code: Select all

<?php

if (!preg_match('/index\.php(?:\?|$)/', $_SERVER['REQUEST_URI'])
    && in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD'))) {
    // cache();
    // for security reasons we only cache the start page for now:
    if ($_SERVER['QUERY_STRING'] === '') {
        cache();
    }
}

function cache()
{
    global $cachefilename;

    $cache = __DIR__ . '/cache/';
    if (!file_exists($cache)) {
        mkdir($cache, 0777);
        chmod($cache, 0777);
    }
    $filename = $cache . md5("$cache{$_SERVER['QUERY_STRING']}") . '.html';
    if (file_exists($filename)) {
        readfile($filename);
        exit;
    } else {
        $cachefilename = $filename;
    }
} 
Insert the following code fragment in XH_finalCleanUp() line 1554:

Code: Select all

    global $cachefilename;

    if (!XH_ADM && isset($cachefilename)) {
        file_put_contents($cachefilename, $html);
    } 
After these modifications responses to each GET (and HEAD) request will be cached in cmsimple/cache/ (if the folder is not created automatically, do it manually and set write permissions (0777), and if already cached will be delivered from the cache. To be able to administrate the site, you explicitly have to request /domain-root/index.php. After each modification to the page cmsimple/cache/ has to be emptied manually (that could be automated for each logout, though).

In my local development environment that gave a nice performance boost (access via index.php, i.e. without caching, took roughly 700 ms, access to already cached pages took around 200 ms).

Warning: for security reasons the code should not be used on a production server. As far as I can see, there are no issues (but, of course, I could be wrong) – at least if there are no protected pages (Memberpages/Register) involved, which would loose their protection!
Last edited by cmb on Tue May 31, 2016 5:34 pm, edited 1 time in total.
Reason: edited code for security reasons
Christoph M. Becker – Plugins for CMSimple_XH

bca
Posts: 293
Joined: Tue Sep 15, 2009 4:49 pm

Re: Load first page faster

Post by bca » Fri May 27, 2016 3:30 pm

Hi Christoph
That looks interesting. I'll try it later.
Of course, that accelerates accessing the start page, but accessing any other page would trigger loading of the stylesheet nonetheless, and so the CSS would have to be transferred a second time.
I dont mind if other pages are served slower. I just need people to get the first page quickly and so it seems does Google.

Am i assuming the cache would be created by the first visit to the page or would it be created manually?

B

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load first page faster

Post by cmb » Fri May 27, 2016 3:43 pm

bca wrote:
Of course, that accelerates accessing the start page, but accessing any other page would trigger loading of the stylesheet nonetheless, and so the CSS would have to be transferred a second time.
I dont mind if other pages are served slower. I just need people to get the first page quickly and so it seems does Google.
I haven't kept a record of it, but I suppose that I do more often click a deep link than a link to a domain's start page. Of course, others may have other preferences. :)
bca wrote:Am i assuming the cache would be created by the first visit to the page or would it be created manually?
The former. Or to be more precisely, the complete query string (everything after the question mark) is regarded. That's a minor detail wrt. the pages accessed via the menu, but you can see the effect when using the search form where you'll get the proper result (even when taken from the cache). The drawback: the cache might get really large. One would have to keep an eye on it.
Christoph M. Becker – Plugins for CMSimple_XH

Holger
Site Admin
Posts: 3470
Joined: Mon May 19, 2008 7:10 pm
Location: Hessen, Germany

Re: Load first page faster

Post by Holger » Fri May 27, 2016 6:27 pm

Hi B,

is it still the same problem as in this post? http://cmsimpleforum.com/viewtopic.php? ... 063#p50008

I think it would be better to find the reason for the long response time when PHP is involved...
cmb wrote:The drawback: the cache might get really large. One would have to keep an eye on it.
Yes. And calling the page with random GET-Values will "eat" your webspace :? .

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load first page faster

Post by cmb » Fri May 27, 2016 8:09 pm

Holger wrote:I think it would be better to find the reason for the long response time when PHP is involved...
ACK
Holger wrote:
cmb wrote:The drawback: the cache might get really large. One would have to keep an eye on it.
Yes. And calling the page with random GET-Values will "eat" your webspace :? .
No, because:
cmb wrote:Warning: for security reasons the code should not be used on a production server.
:P

Kidding aside: of course this is an issue that would have to be solved, if the script were to be developed further.
Christoph M. Becker – Plugins for CMSimple_XH

meltemi
Posts: 177
Joined: Sat Feb 22, 2014 10:11 pm
Location: Franken (Deutschland)
Contact:

Re: Load first page faster

Post by meltemi » Fri May 27, 2016 10:37 pm

gtmetrix says:

[PageSpeed]
Specify image dimensions
Serve scaled images
Minify CSS
Avoid CSS @import

[YSlow]
Make fewer HTTP requests

Additionally I say:

1.
Check the response time of your server at different daytimes.

2.
Why do you use two trackers?

3.
This response is wrong:

Code: Select all

Expires	Thu, 19 Nov 1981 08:52:00 GMT
The home page never will be loaded from cache, always from server.

bca
Posts: 293
Joined: Tue Sep 15, 2009 4:49 pm

Re: Load first page faster

Post by bca » Sat May 28, 2016 9:43 am

@holger
It's not exactly a return to the previous problem. My isp insists there is nothing wrong at their end and I should try going for their more expensive hosting where there is only me on the server. Might have been called VPS.

@meltemi you tested the original page. I haven't yet made the new page live although it can be tested at www.videopoint.co.uk/index.html.
As Google is the one that is important I was following their guidelines on Google pagespeed insights. They say that a fast site is favoured in their search results. I am getting a score of 99/100 with the html page. Google don't seem worried about image sizes but yes I should fix that.
Where does that 1981 date come from?

B

cmb
Posts: 14225
Joined: Tue Jun 21, 2011 11:04 am
Location: Bingen, RLP, DE
Contact:

Re: Load first page faster

Post by cmb » Sat May 28, 2016 10:46 am

bca wrote:Where does that 1981 date come from?
It is sent by PHP to disable client side caching. You (or maybe your provider) can change session.cache_limiter in php.ini to the desired value, see http://php.net/manual/en/function.sessi ... imiter.php for a description (currently, it's obviously set to private or nocache).

However, this header will only be sent, when a session has been started, and obviously that is the case on videopoint.co.uk. CMSimple_XH is not supposed to start a session when not in admin mode, though. So I assume that is a plugin or another extension that starts the session[1]. Anyhow, the session might explain the performance problems, because while a session is open the file is locked, so other requests with the same session ID will be blocked.

[1] That might be the statcounter. Did you measure performance without it?
Christoph M. Becker – Plugins for CMSimple_XH

Post Reply