How to optimize wordpress site speed checklist

Things to optimize are:

  • server connection time
  • time to first byte
  • number of server requests
  • total size of downloaded content

Before you start optimizing, test your site's performance using https://tools.keycdn.com/performance

  1. Request to server
    1. DNS request
      • Here it's probably interesting to switch to a CDN because they usually have faster DNS servers than the standard providers.
    2. connect to server
    3. SSL handshake
  2. Server processing
    1. i/o and memory
    2. httpd
    3. php
    4. mysql
    5. load and execute wordpress
    6. load and execute themes and active plugins
  3. server gives response to client (time to first byte)
    1. update apache to the latest version, something like 2.4.x. to check your version httpd -v
    2. add caching plugin to wordpress W3 total cache
      • page cache enable - disk enhanced
      • minify disable - modpagespeed will do that
      • Opcode Cache enable - zend opcache (enable it in php.ini by uncommenting zend_extension=opcache)
      • Database cache enable - disk
      • Object cache enable - disk
      • Browser cache disable - modpagespeed will do that
      • Fragment cache enable - disk
    3. add modpagespeed to site
      • ...
    4. move to http/2 https://icing.github.io/mod_h2/howto.html
      • in http.conf, uncomment
        LoadModule http2_module modules/mod_http2.so<IfModule http2_module>
        LogLevel http2:info
        </IfModule>
      • in virtual hosts, add this
        # for a https serverProtocols h2 http/1.1# for a http server
        Protocols h2c http/1.1
      • An additional requirement is that no cipher from a specified black list may be used. An acceptable Apache SSL configuration regarding this is:
        SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
        SSLProtocol All -SSLv2 -SSLv3
      • restart apache and test it: https://tools.keycdn.com/http2-test or chrome://net-internals/#http2
    5. change apache from mpm_prefork to mpm_worker/mpm_event
      • check apache server mpm type using httpd -V
      • install php-fpm package
      • start php-fpm service
      • edit httpd.conf and switch to event or worker
        LoadModule mpm_event_module modules/mod_mpm_event.so
        #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
        #LoadModule mpm_worker_module modules/mod_mpm_worker.so
      • uncomment
        LoadModule proxy_module modules/mod_proxy.so
        LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
      • create new httpd config file php-fpm.conf
        DirectoryIndex index.php index.html
        <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
        </FilesMatch>
      • include it at the bottom of httpd.conf
        Include conf/extra/php-fpm.conf
      • restart services php-fpm and httpd
    6. get rid of not used apache modules. to check which modules are used httpd -M
    7. check apache workers count and memory usage httpd-mpm.conf
    8. get rid of unnecessary wordpress plugins
    9. speed can be tested with xdebug
      • install xdebug
      • edit /etc/php/conf.d/xdebug.ini
        zend_extension="/usr/lib/php/modules/xdebug.so"

        ; profiler https://xdebug.org/docs/profiler
        xdebug.profiler_enable_trigger = 1
        xdebug.profiler_enable_trigger_value = "test"
        xdebug.profiler_output_dir = "/var/log/xdebug"
        xdebug.profiler_output_name = "callgrind.%s.%H"

      • systemctl restart httpd
        systemctl restart php-fpm
      • You can test if xdebug is working with the following code in a php file:
        function test()
        {
        echo "Called @ ".xdebug_call_file().
        ":".xdebug_call_line()." from".
        xdebug_call_function();
        }

        test();

      • to test the profiler https://octopuslabs.io/blog/?XDEBUG_PROFILE=test

references: https://www.tecmint.com/apache-performance-tuning/
https://www.digitalocean.com/community/tutorials/how-to-optimize-apache-web-server-performance