top of page
Search

Wordpress

  • knowledgediary4min
  • Mar 2, 2020
  • 7 min read

Updated: Mar 3, 2020



WordPress Optimization

When to Use This

This is for use when a customer has indicated that a specific WordPress installation is slow. After ruling out issues like a hardware node issue, then proceed with the following optimizations.

We need WordPress admin credentials (and URL) to make these changes. Also prior to making any of these changes, check with the customer. Also please understand that while these changes will work in 95% of the WordPress installations that you will find, it's important to test the sites after making any modifications. Also keep in mind that the following are small changes to eek out slightly better performance from a WordPress site. If they are having performance issues and prior to spending time optimizing the things below look for things like OOMs, disk I/O and CPU utilization in Grove >> Monitoring >> Server Performance, etc. and make recommendations on upgrades because the following are not replacements for those issues. Think of this as augmenting things like additional RAM, LiteSpeed, plan upgrades. etc.

If you're uncertain on any of the following items, then please ask a manager prior to making the change.

Areas of Focus:

Caching and WordPress settings Image optimization Database optimization Apache/PHP optimization

The above areas will provide a solid basis for optimizing a WordPress installation while maintaining our standard managed services.

Caching and WordPress Settings

By default, WordPress has no built-in caching system. This can cause performance issues, specifically for large/busy sites. The solution is to install memcached system service and the associated memcache PHP module and then install/configure W3 Total Cache to utilize it.

Install memcached + PHP memcache support.  Search, install, and activate the W3 Total Cache plugin via the Plugins >> Add New interface.  Once the W3 Total Cache Plugin has been activated it will redirect to the Installed Plugins page and from there, click on the W3 Total Cache Settings link. Select disk-enhanced from the drop-down box for the following items:

Page cache method Select memcached from the drop-down box for the following items:

Database Cache Method Object Cache Method

Once you've selected the above options, click Save All Settings AND click on Empty Cache.

There are also other settings that are disabled by default which may help improve page load times. The following can break sites, so we do not officially recommend the following.

Performance >> Minify  >> HTML & XML and click the checkbox next to: Enable, Inline CSS minification, Inline JS minification, and Line break removal. Make sure NOT to check Don't minify feeds. Click Save All Settings and if prompted, clear cache.

The Minify feature can cause javascript issues with certain plugins or load issues. We do not recommend enabling it within W3TC for these reasons!

Performance >> Browser Cache >> General  and click the checkbox next to: Set expires header, Set cache control header, and Set entity tag (eTag). Click Save All Settings and if prompted, clear cache.

Why don't we use memcached for page caching?

Page Caching Benchmarks

Testing a default WordPress installation with the Theme Unit Test data imported (https://codex.wordpress.org/Theme_Unit_Test). Testing locally using the following command:

root@wiredtree [~]# ab -c 1 -n 100 http://wordtest.etcet.net/

No page caching:

Requests per second:    1.06 [#/sec] (mean)

Connection Times (ms)

min  mean[+/-sd] median   max

Connect:        0 0 0.0 0 0

Processing:   877 941 110.2 917 1658

Waiting:      603 651 63.8 640 1115

Total:        877 941 110.2 917 1658

Page caching w/ memcache:

Requests per second:    9.30 [#/sec] (mean)

Connection Times (ms)

min  mean[+/-sd] median   max

Connect:        0 0 0.0 0 0

Processing:    95 107 97.1 97 1068

Waiting:       89 100 95.5 91 1045

Total:         95 107 97.1 98 1068

Page caching w/ disk enhanced:

Requests per second:    89.15 [#/sec] (mean)

Connection Times (ms)

min  mean[+/-sd] median   max

Connect:        0 0 0.0 0 0

Processing:     1 11 98.9 1 990

Waiting:        1 11 96.7 1 968

Total:          1 11 98.9 1 990

As you can see, page caching using disk enhanced outperforms using memcache. To find out how it achieves this, look in the .htaccess file for the site. You'll see there are some complicated rewrite rules created by W3TC. These rewrite rules are used to serve up cache hits. With these rules in place, a cache hit will essentially be on-par with the performance of static content. This is compared to using memcache which requires PHP to be processed to perform a cache lookup.

Other WordPress caching plugins that use .htaccess rewrite rules to perform cache lookups include WP Super Cache (with mod_rewrite caching enabled).

Image Optimization

There are other useful plugins that may help reduce page load times, specifically with image-heavy sites. The plugin is called WP smush.it and will automatically optimize every image you upload by removing all of the non-essential data from the photos like creation date, camera used for the photo, gps coordinates, etc.

Search, install, and activate the WP Smush.it plugin. If prompted, click the Empty Page Cache button.

This will only smush newly uploaded images and NOT the previously uploaded images. As of version 1.4.0 there is a new, experimental Bulk Smush.it feature. You can find the link under the Media Library tab. Heed the warning that it's experimental and inform the customer about this PRIOR to running it.

Database Optimization

This section is going to deal with optimizing the database table types and making recommendations based on things like number of rows. This is not dealing with optimizing the MySQL/MariaDB configuration file itself. Having said that, the default table type for WordPress databases are MyISAM. MyISAM tables are great for simple storage are better at fulltext searches and such, but MyISAM suffers from table-level locking. This is problematic for heavily trafficked sites that rely on concurrent queries to the same table leading to the dreaded 'Locked Table' output in the process listing, queued queries, and bad performance.

The solution is to switch the tables over to InnoDB. InnoDB does row-level locking and allows multiple concurrent queries to be run against the same table. What this ultimately leads to is fewer locked table and overall faster page load times and less system resource utilization. There are caveats however:

Not all themes and/or plugins are going to be compatible with InnoDB. You need to be explicitly clear to the customer that they need to check with their developer (or theme/plugin developer) to see if they are going to work. It's not our responsibility to check for compatibility as we are just making general performance recommendations. Nearly all up-to-date core WordPress, themes, and plugins will work, but double-check with the customer prior to making any changes. The tables that you are converting must not contain FULLTEXT indexes as they are not compatible with InnoDB.

Use the following SQL query to determine if the above is true:

MySQL 5.5+

SELECT tbl.table_schema, tbl.table_name FROM

(SELECT table_schema, table_name FROM information_schema.tables WHERE 1=1 AND engine = 'MyISAM' AND table_schema NOT IN ('information_schema', 'mysql', 'performance_schema')) tbl

INNER JOIN

(SELECT table_schema, table_name FROM information_schema.statistics WHERE index_type = 'FULLTEXT') ndx

USING (table_schema, table_name);

MySQL 5.4 and Lower

SELECT tbl.table_schema, tbl.table_name FROM

(SELECT table_schema, table_name FROM information_schema.tables WHERE 1=1 AND engine = 'MyISAM' AND table_schema NOT IN ('information_schema', 'mysql')) tbl

INNER JOIN

(SELECT table_schema, table_name FROM information_schema.statistics WHERE index_type = 'FULLTEXT') ndx

USING (table_schema, table_name);

If the above doesn't return any warnings or errors, then you can safely convert the tables to InnoDB. But you ABSOLUTELY need to do the following:

Document current MySQL/PHP settings as a ticket note: cat /usr/local/cpanel/version ; echo; httpd -v; echo; /usr/local/cpanel/bin/rebuild_phpconf --current; echo; grep ^extens /usr/local/lib/php.ini; echo; php -v; echo; mysql -V; Generate backups using SQL dumps for all databases (just in case): mkdir /home/mysql.back && for i in $(mysql -BNe 'show databases'| grep -v _schema);do echo $i; sudo mysqldump $i > /home/mysql.back/$i.sql ; done

Once you have done  the above, then you can proceed with the conversion:

Conversion

$ DATABASENAME="cpanelusername_dbname"

$ for t in `echo "show tables" | mysql --batch --skip-column-names $DATABASENAME`; do mysql $DATABASENAME -e "ALTER TABLE \`$t\` ENGINE = InnoDB;"; done

Another area within database optimization that can create performance issues is the row size on some of the tables. Switching over to InnoDB helps with this but if there is a table with 1 million+ rows, it's going to cause performance issues. Finding largest tables on MySQL instance is simple in MySQL 5.0+ thanks to Information Schema and you can use the following query to output that information for the top 10 tables:

SELECT CONCAT(table_schema, '.', table_name),

CONCAT(ROUND(table_rows / 1000000, 2), 'M')                                    rows,

CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G')                    DATA,

CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G')                   idx,

CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') total_size,

ROUND(index_length / data_length, 2)                                           idxfrac

FROM information_schema.TABLES

ORDER BY data_length + index_length DESC

LIMIT  10;

With the information from above, you can recommend that the customer take a look to see if any of the old data can be truncated (removed). The end result would be fewer rows to iterate through and faster overall performance.

Apache/PHP Optimization

While using SuPHP as the default PHP handler makes managing file and folder ownership and permissions simple, it's generally considered to be the slowest handler. And it does not allow for effective use of op-code caching systems like XCache or Zend Opcache. In order to retain the manageability of SuPHP-style permissions with the benefits of something like DSO/cgi, then we will need to compile Apache with support for mod_ruid2. Some important caveats:

LiteSpeed is not compatible with mod_ruid2. Do NOT try to install mod_ruid2 if they are running it. If they are running an older version of PHP like 5.2.x that's not in EasyApache, then you will need to work with them on upgrading that PHP version. Mod_ruid2 is still marked as experimental and while unlikely, it can cause oddities with page loads. You need to make sure that you alert the customer to this prior to recompiling Apache with mod_ruid2.

We highly recommend going with Zend Opcache over any other PHP opcode caching alternative. If the server is running PHP 5.5.x, then you just need to add zend_extension="opcache.so" to /usr/local/lib/php.ini and restart Apache for it to load.

There are two methods of installing Zend Opcache for PHP 5.3.x or 5.4.x:

Install through PECL (preferred): pecl install channel://pecl.php.net/ZendOpcache-7.0.3 Via source:

Zend Opcache Install

cd /usr/local/src

wget http://pecl.php.net/get/ZendOpcache

# to get the latest (master) build do the following instead:

tar xvfz zendopcache-7.x.x.tgz

cd zendopcache-7.x.x

phpize

whereis php-config

# set the path below

./configure --with-php-config=/usr/local/bin/php-config

make

make install

# note the opcache.so install path because you will use it below

vi /usr/local/lib/php.ini




Block Access to xmlrpc.php Server Wide


Blocking xmlrpc.php access will break Jetpack. A lot of customers and their respective clients use it. Don't blindly redirect all requests to xmlrpc.php without checking with them first (or go ahead and block it if it's causing a big problem, and then let them know what you did and how it can affect their sites!).

Step-by-step guide

Edit /usr/local/apache/conf/includes/pre_main_global.conf

Add the following to the bottom of this include file:

<IfModule mod_alias.c>

RedirectMatch 301 ^.*/xmlrpc.php$ http://127.0.0.1/

</IfModule>



Restart httpd. (service httpd restart)

Test accessing xmlrpc.php on a WordPress site on the server. (e.g. www.example.org/xmlrpc.php)



One liner to add redirect to pre_main_global and restart



echo '<IfModule mod_alias.c>

RedirectMatch 301 ^.*/xmlrpc.php$ http://127.0.0.1/

</IfModule>' >> /usr/local/apache/conf/includes/pre_main_global.conf

service httpd restart


EA4 note

/etc/apache2/conf.d/includes/pre_main_global.conf is the EasyApache 4 location. It looks like this is a hard link to/from the files in /usr/local/apache/conf/includes which is preferable as a common location between CentOS 6 and 7, and EA3 and EA4.


We can confirm that the httpd program is looking for content in /etc/apache2/conf.d/ and not /usr/local/apache/conf/:


# strace httpd -t 2>&1 | grep ^open | grep conf


Be sure to restart httpd after adding this file directive to the include file.

 
 
 

Recent Posts

See All
clear script

#!/bin/bash rm -f ./cleanspace.sh bold=$(tput bold) normal=$(tput sgr0) TIMESTAMP=$(date +%d-%m-%Y-%H-%M) LOGFILE="/root/cleardisk-$TIME...

 
 
 
innodb restore

Create a new folder: mkdir /var/lib/mysql2 From R1: Restore from the /var/lib/mysql folder: + The folder which is called the db name...

 
 
 
Scripts

#not wordpress site grep shop2vizag.com /var/log/messages | awk '{print $6}' | cut -d: -f1 |sort -n |uniq -c |sort -n #Domains using...

 
 
 

Comments


  • White Facebook Icon
  • White Twitter Icon
  • White Instagram Icon
  • White YouTube Icon

© 2023 by Knowledge4mind. Proudly created with Wix.com

bottom of page