Settings to Optimize Page Loading Speed

hongtrang

Member
From my experience, I would like to share some ways to speed up page loading (apart from adding server hardware configuration). Hope it helps someone in need.
1. Enable HTTP2 and Brotli (if your webserver supports it)
2. Install and configure Zend Opcache to speed up PHP processing and reduce CPU load.
3. Install Memcached (or you can choose another, but I choose Memcached because it's easy to use :D)
4. Create a .htaccess file to cache the content and images. Eg:
Code:
Header set Strict-Transport-Security "max-age=10886400; includeSubDomains; preload"
# X-Content-Type nosniff
<IfModule mod_headers.c>
    Header set X-Content-Type-Options nosniff
</IfModule>
<IfModule mod_headers.c>
  Header set X-XSS-Protection "1; mode=block"
</IfModule>
<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon
</IfModule>
###################################################
# Exception: Images
SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png)$ no-gzip dont-vary
# Drop problematic browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Make sure proxies don't deliver the wrong content
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
</IfModule>
## EXPIRES CACHING ##
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 2 month"
    ExpiresByType application/atom+xml "access plus 2 hour"
    ExpiresByType application/rdf+xml "access plus 2 hour"
    ExpiresByType application/rss+xml "access plus 2 hour"
    ExpiresByType application/json "access plus 0 seconds"
    ExpiresByType application/ld+json "access plus 0 seconds"
    ExpiresByType application/schema+json "access plus 0 seconds"
    ExpiresByType application/vnd.geo+json "access plus 0 seconds"
    ExpiresByType application/xml "access plus 0 seconds"
    ExpiresByType text/xml "access plus 0 seconds"
    ExpiresByType image/vnd.microsoft.icon "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType text/html "access plus 1 minute"
    ExpiresByType text/javascript "access plus 2 month"
    ExpiresByType text/x-javascript "access plus 2 month"
    ExpiresByType application/javascript "access plus 2 months"
    ExpiresByType application/x-javascript "access plus 2 months"
    ExpiresByType image/jpg "access plus 2 month"
    ExpiresByType image/jpeg "access plus 2 month"
    ExpiresByType image/gif "access plus 2 month"
    ExpiresByType image/png "access plus 2 month"
    ExpiresByType image/svg+xml "access plus 2 month"
    ExpiresByType image/bmp "access plus 21 month"
    ExpiresByType image/webp "access plus 2 month"
    ExpiresByType audio/ogg "access plus 1 month"
    ExpiresByType video/mp4 "access plus 1 month"
    ExpiresByType video/ogg "access plus 1 month"
    ExpiresByType video/webm "access plus 1 month"
    ExpiresByType text/plain "access plus 2 month"
    ExpiresByType text/x-component "access plus 2 month"
    ExpiresByType application/manifest+json "access plus 2 week"
    ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
    ExpiresByType text/cache-manifest "access plus 0 seconds"
    ExpiresByType application/pdf "access plus 2 month"
    ExpiresByType application/x-shockwave-flash "access plus 2 month"
    ExpiresByType application/vnd.ms-fontobject "access plus 2 month"
    ExpiresByType font/eot "access plus 2 month"
    ExpiresByType font/opentype "access plus 2 month"
    ExpiresByType application/x-font-ttf "access plus 2 month"
    ExpiresByType application/font-woff "access plus 2 month"
    ExpiresByType application/font-woff2 "access plus 2 month"
    ExpiresByType application/x-font-woff "access plus 2 month"
    ExpiresByType font/woff "access plus 2 month"
    ExpiresDefault "access plus 10 days"
</IfModule>
    #Alternative caching using Apache's "mod_headers", if it's installed.
    #Caching of common files - ENABLED
<IfModule mod_headers.c>
    # 1 Month
    <filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|svg|js|css|swf)$">
            Header set Cache-Control "max-age=2592000, public"
    </filesMatch>
    # 2 DAYS
    <FilesMatch "\.(xml|txt)$">
    Header set Cache-Control "max-age=172800, public, must-revalidate"
    </FilesMatch>
    # 2 HOURS
    <FilesMatch "\.(html|htm)$">
    Header set Cache-Control "max-age=7200, must-revalidate"
    </FilesMatch>
</IfModule>
<IfModule mod_headers.c>
  <FilesMatch "\.(js|css|xml|gz|html|ttf)$">
    Header append Vary: Accept-Encoding
  </FilesMatch>
</IfModule>
# Set Keep Alive Header
# This *just* sets the header - maybe your hoster is not allowing this feature
# Please check if it is working with tools like http://www.webpagetest.org
<IfModule mod_headers.c>
    Header set Connection keep-alive
</IfModule>
# If your server don't support ETags deactivate with "None" (and remove header)
<IfModule mod_expires.c>
  <IfModule mod_headers.c>
    Header unset ETag
  </IfModule>
  FileETag None
</IfModule>
5. Install and configure add-ons: Lazy Load 2.5.1 and Font Awesome Manager.
6. Enable cache in config.php
Code:
//Used: Brotli
$config ['enableGzip'] = false;
//Cache
$config['cache']['enabled'] = true;
$config['cache']['css']['enabled'] = true;
$config['cache']['sessions'] = true;
$config['cache']['provider'] = 'Memcached';
$config['cache']['config'] = [
        'server' => [
            ['127.0.0.1',11211]
        ]
    ];
$config['pageCache']['enabled'] = true;
$config['pageCache']['lifetime'] = 600;
$config['cache']['context']['page']['provider'] = 'Memcached';
$config['cache']['context']['page']['config'] = [
        'server' => [
            ['127.0.0.1',11211]
        ]
    ];
 
1. Choose your style/theme carefully - if it's poorly laid out and suboptimal to begin with, you'd have a uphill battle to speed it up ;)
2. Be picky about what and how much javascript you add externally on top of what Xenforo already serves :)
3. Learn how to properly use Cloudflare and it's features to make it fast for all visitors on your forums from around the world :D
4. Optimize your backend server stack - web server, PHP, MySQL server to ensure it's working well - the slowest part of your forums will always be a cache miss/logged in visitor's request! 😊
 
Yes.
I was too greedy before when configuring MariaDB made my server always overload :(
My forum is also taking too long to load third party js.
Optimizing the style/theme will reduce the loading time of the DOM
 
Thanks for this.

I had most of it, but I added the cache in config.php trick :)
 
Last edited:
Currently my desktop score is pretty good.

1646167033706.png

But my mobile is abyssmal... :ROFLMAO:

1646167056385.png

I've spent a lot of time trying to optimize, finding best Cloudfare settings, etc..
 
//Used: Brotli $config ['enableGzip'] = false; //Cache $config['cache']['enabled'] = true; $config['cache']['css']['enabled'] = true; $config['cache']['sessions'] = true; $config['cache']['provider'] = 'Memcached'; $config['cache']['config'] = [ 'server' => [ ['127.0.0.1',11211] ] ]; $config['pageCache']['enabled'] = true; $config['pageCache']['lifetime'] = 600; $config['cache']['context']['page']['provider'] = 'Memcached'; $config['cache']['context']['page']['config'] = [ 'server' => [ ['127.0.0.1',11211] ] ];
What if I use opcache? Do I need to add something similar from above to my config.php? Cache is not enabled automatically in XF?
 
Okay this is my config.php:

Code:
<?php

$config['db']['host'] = 'localhost';
$config['db']['port'] = '3306';
$config['db']['username'] = 'xx';
$config['db']['password'] = 'xx';
$config['db']['dbname'] = 'xx';

$config['fullUnicode'] = true;

//Used: Brotli
$config ['enableGzip'] = false;
//Cache
$config['cache']['enabled'] = true;
$config['cache']['css']['enabled'] = true;
$config['cache']['sessions'] = true;
$config['cache']['provider'] = 'Memcached';
$config['cache']['config'] = [
        'server' => [
            ['127.0.0.1',11211]
        ]
    ];
$config['pageCache']['enabled'] = true;
$config['pageCache']['lifetime'] = 600;
$config['cache']['context']['page']['provider'] = 'Memcached';
$config['cache']['context']['page']['config'] = [
        'server' => [
            ['127.0.0.1',11211]
        ]
    ];
I've confirmed Memcached is installed and running, but I get this on my forum:

Code:
This page isn’t working right nowzoldos.net can't currently handle this request.
HTTP ERROR 500
I did use SASL and set up a username and password for it. So how do I add this to the config.php which I'm assuming will fix it? Thanks!
 
Wow, enabled WinCache on my site and got below 300ms which is the fastest MySQL website on our server now!
I adapted from what I saw in this thread, so not sure if it's correct!

Any tweak suggestions?

PS I had to remove the sessions on my setup, it was causing HTTP 500 errors for some reason on Windows Server.
// REMOVED $config['cache']['sessions'] = true;



//Cache
$config['cache']['enabled'] = true;
$config['cache']['css']['enabled'] = true;
$config['cache']['provider'] = 'WinCache';
$config['pageCache']['enabled'] = true;
$config['pageCache']['lifetime'] = 600;
$config['cache']['context']['page']['provider'] = 'WinCache';

Also using MaxCDN for CDN
$config['externalDataUrl'] = 'CDN URL';
$config['javaScriptUrl'] = 'CDN URL';


gtmetrix.webp
 
Last edited:
I got 2 GTMetrix scores. One for the site homepage and one for the forums. Image 1 is the homepage which is Wordpress (over 13,600 articles on the site) and the Image 2 is the Xenforo forums. On the Wordpress side I could never get below 1.0 second load time with Nginx. LSWS got it about another 0.5 seconds lower. I'm a firm believer in Litespeed.

I'm running Liquid Web, Litespeed (PHP 7.4.28), PixelExit Theme (Nova), Cloudflare.

GTMetrix04172022Homepage.jpgGTMetrix04172022Forums.jpg
 
Found a new extension from @Nulumia called XFOptimized- https://xenforo.com/community/resources/xfoptimize-minify-preconnect-preload.8581/

Works great! Our score would be even higher, but we have Google, Amazon and Facebook .JS loading on the page as well.

We are using PHP 8.1.5 as well. I actually think we can get the score a little higher with more tweaks.

performance.jpg

@RaptureForums when I ran a forum test it was much lower- https://gtmetrix.com/reports/www.raptureforums.com/BUUo755a/
did you change something?
 
Last edited:
@RaptureForums when I ran a forum test it was much lower- https://gtmetrix.com/reports/www.raptureforums.com/BUUo755a/
did you change something?

No, but each time you reload a URL, you will or can potentially get a different score (better or worse). The one I posted is a "general" or "average" of what I usually get when I do a run. Or at least is representative of the samples I have taken on the past 6 months. :-)

This one is done just now: https://gtmetrix.com/reports/www.raptureforums.com/inmLx5qr/

The biggest take away is that these services can help you find things that you can work on to get better scores and at the same time have a site that provides a great user experience. BUT, don't get addicted or hooked on the numbers and scores. You will drive yourself insane if the numbers and scores are all you are focusing on. I've got my site where I am happy with it. Could it be better? Sure. But I'm not going to obsess over it. Focusing on numbers and scores can lead to being on a rollercoaster of emotions if you let it. Sometimes getting to a "happy place" with your GTMetrix (or similiar service) is most of the battle. I haven't done any "tweaks" on my site in probably 6 months.

In my case, I've got to watch my blood pressure. :LOL:

ETA: I've just put in a request for my web host to upgrade my PHP from 7.4.28 to 8.1. It will be interesting to see if that helps any.
 
Last edited:
Top Bottom