This article about WordPress optimization is mostly written for developers who know how to create website with WordPress but not very well-versed with other tricks to optimize WordPress for speedy delivery of the content of their website. But anyone can use some of these tricks to improve their non-WordPress websites. I am using my own website pthakkar.com for this blog as I am going through the same pain of optimizing my own website. So lets start.
If you profile a web page with Google Page Speed, it calculates the page’s performance by using number of different rules. These rules are general front-end best practices we can apply at any stage of web development. If you are interested in understanding these rules, you can find at https://developers.google.com/speed/docs/insights/rules — you can refer to these pages at any time. It gives us specific tips and suggestions for how we can best implement the rules and incorporate them into our development process.
When I created my website pthakkar.com with wordpress, it was not optimized at all as you can see from my test run for Google Page Speed. It got an overall PageSpeed Score of 54 (out of 100) which was way too low.
Google Page Speed Overview of PThakkar.com
So I started step by step process to take Page Speed score above 90. Page Speed evaluates performance from the client point of view, typically measured as the page load time. The best practices involves many steps that affect page load time, including resolving DNS names, setting up TCP connections, transmitting HTTP requests, downloading resources, fetching resources from cache, parsing and executing scripts, and rendering objects on the page and they are grouped in six different categories by Google.
Optimizing caching - keeping your application’s data and logic off the network altogether
Minimizing round-trip times - reducing the number of serial request-response cycles
Minimizing request overhead - reducing upload size
Minimizing payload size - reducing the size of responses, downloads, and cached pages
Optimizing browser rendering - improving the browser’s layout of a page
Optimizing for mobile - tuning a site for the mobile networks and mobile devices
All of the above rules are bit complex for normal WordPress users who does not have experience in performance optimization. So many developers from WordPress community have created plugins to do various optimization using WordPress interfaces. I will list these plugins one by one with advantages and disadvantages of each of them and we will use the best one to optimize my website pthakkar.com. After applying all the optimization techniques, we will compare Google Page Speed score to see how much improvement each plugin did in terms of Google Page Speed score. some of these optimization tricks require some php programming knowledge.
Optimization by tweaking the Configuration File
My WordPress website required to make database calls to locate the site URL. We can greatly reduce database calls just to locate the site URL by defining the site URL in the WordPress configuration file, wp-config.php , as below:
After tweaking the Configuration file, I wanted to see what was the Google Page Speed score and but it still stayed same so I decided to find some plug-ins which might help me in making my website faster so I searched through all available WordPress plug-ins and I found two that were most recommended and the most downloaded, W3 Total Cache and WP Super Cache. So I decided to understand the differences between two and found that W3 Total Cache is far more powerful although tough to configure. If you need more information, please read a blog from tentblogger.
After understanding what W3 Total Cache plugin can do, I installed it and started configuring it. It provided various option for using cache so I tried to understand different caching options and found two of them very compelling, APC or Alternative PHP Cache and MemCache. After reading pros and cons of both of them, I thought APC would be best option for me as I am running single blog on virtual server so I tried installing APC but for PHP 5.3, it was not a simple job as my server was a bare-bone linux distro. It did not have APC, nor any development tools like “c” compiler. So I decided to install all development tools on my CentOS server. Using following command you can find out what php packages are installed on your server.
#yum list installed | grep php
php53.i386 5.3.3-13.el5_8 installed
php53-cli.i386 5.3.3-13.el5_8 installed
php53-common.i386 5.3.3-13.el5_8 installed
php53-devel.i386 5.3.3-13.el5_8 installed
php53-gd.i386 5.3.3-13.el5_8 installed
php53-mysql.i386 5.3.3-13.el5_8 installed
php53-pdo.i386 5.3.3-13.el5_8 installed
I needed php53-devel and pcre-devel for my work as I needed phpize command which required php53-devel. I used following command to install both of them.
#yum install php-devel pcre-devel
Then, I needed to compile a package, I needed a C compiler (like gcc) and make. The easiest way to install all the needed development tools was using groupinstall.
#yum groupinstall "Development Tools"
Now I needed to download APC package so I went to my home directory and downloaded and expanded the package using following commands.
#tar -zxvf APC-3.1.9.tgz
To set up APC, we needed to go to the expanded directory.
Once in the directory, running phpize command would give output like below;
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
Once we had this, we needed to find the php-config file using following command:
php-config: /usr/bin/php-config /usr/share/man/man1/php-config.1.gz
In my case I found php-config file in ‘/usr/bin’ and used it for the next command ‘configure.
./configure --enable-apc --enable-mmap --with-apxs --with-php-config=/usr/bin/php-config
Basically, this command tells OS to compile APC as a dynamically loadable module or DSO. You pass the –with-apxs option to the configure script. If you know the location of the Apache apxs file, you can supply that to the switch with –with-apxs=/usr/local/apache/apxs.
Click on apxs – APache eXtenSion tool if you need to know more about apxs. Darrell Brogdon has given good explanation about –with-apxs switch.
Once you have run configure command, run following command.
Now, if you have an /etc/php.d/ directory on your CentOS server, create a file called apc.ini in your /etc/php.d directory which will have all your configuration settings and if it already exists, you can just edit the existing one. If your CentOS server doesn’t have an /etc/php.d directory, find your php.ini file and add these configuration settings to it. Normally php.ini file is located in /etc.
You can use following code as an example for apc.ini file. It is with lots of comments to give you better understanding.
; Enable the extension module
extension = apc.so
; To get better explanation of options for the APC module, (at the time of writing version = 3.1.9)
; See http://www.php.net/manual/en/apc.configuration.php
; Set apc.enabled to 0 to disable APC.
; The number of shared memory segments to allocate for the compiler cache.
; The size of each shared memory segment, in MB. You can use G for GB.
; A "hint" about the number of distinct source files that will be included or
; requested on your web server. Set to zero or omit if you're not sure;
; Just like num_files_hint, a "hint" about the number of distinct user cache
; variables to store. Set to zero or omit if you're not sure;
; The number of seconds a cache entry is allowed to idle in a slot in case this
; cache entry slot is needed by another entry.
; use the SAPI request start time for TTL
; The number of seconds a user cache entry is allowed to idle in a slot in case
; this cache entry slot is needed by another entry.
; The number of seconds that a cache entry may remain on the garbage-collection list.
; On by default, but can be set to off and used in conjunction with positive
; apc.filters so that files are only cached if matched by a positive filter.
; A comma-separated list of POSIX extended regular expressions.
; If compiled with MMAP support by using --enable-mmap this is the mktemp-style file_mask to pass to the mmap module for determining whether your
; mmap'ed memory region is going to be file-backed or shared memory backed.
; file_update_protection setting delays caching brand new files, value in second(s).
; This setting enables APC for the CLI version of PHP (Mostly for testing and debugging). Possible values; 1 for ON, 0 for OFF.
; Prevent files larger than this value from getting cached
; Whether to stat the main script file and the fullpath includes. If this setting is off, APC will not check, which usually means that
; to force APC to recheck files, the web server will have to be restarted or the cache will have to be manually cleared.
; On a production server where the script files rarely change, a significant performance boost can be achieved by changing its value to 0.
; Vertification with ctime will avoid problems caused by programs such as svn or rsync by making
; sure inodes havn't changed since the last stat. APC will normally only check mtime.
; Whether to canonicalize paths in stat=0 mode or fall back to stat behaviour
; With write_lock enabled, only one process at a time will try to compile an
; uncached script while the other processes will run uncached
; Logs any scripts that were automatically excluded from being cached due to early/late binding issues.
;This setting is deprecated, and replaced with apc.write_lock, so it is set to zero.
Once this is done, restart your apache server.
#service httpd restart
For more information about APC, you can copy the ~/APC-3.1.9/apc.php file in your web root, and then open it in browser. If you can see server stats in that page, you have successfully installed APC on CentOS.
Once APC cache was installed, I needed to configure W3 Total Cache to use APC.
I haven’t used Content Delivery Network so my CDN setting is empty.
Once I did above settings in W3 Total Cache, Google Page Speed for my blog pthakkar.com increased to 97 as per my last check.