101 Tips, Ideas and Resources for Faster WordPress

Number of research has been done to explore a relationship between website speed and bounce and conversion rate. It all comes down to this: the slower the website is, the higher is a bounce and the lover is conversion rate. And with the recent fact about Google started to penalize slow sites, performance assessment and optimization is more important than ever.

We tried to compile a list of all things you can do to make your site load and render faster and we hope this guide will be useful both to WordPress publishers as well as any website owner concerned with website performance.

Some stuff on the list are no-brainers, while others require a deeper knowledge of a technology stack but we strongly suggest you to act on them today, or to hire us to do it for you.

The Ultimate WordPress Performance Guide

Table of Contents

Hosting performance (shared vs dedicated hosting)

importance: high
This one looks like obvious, but sometimes a first step one should take to speed up a site is change a hosting provider.

Shared hosting is what most people get when they start a website. "Shared" means your site share a one big server with hundreds, even thousands other sites. To make sure things run smoothly, hosting companies put limits on how much resources you’re allowed to use at any time; not just limits on bandwidth or storage but also limits on CPU usage or number of simultaneous connections.

For hosting, most of the time you get exactly what you pay for. It’s safe to say that even a cheapest shared hosting should handle 1000-2000 visitors a day. If you need more than that, maybe you should consider VPS, or even a dedicated machine.

With a VPS (Virtual Private Server) you get a fixed share of CPU and memory and more flexibility about version and configuration of software you’d want to use.

With a dedicated server you get a whole machine just for yourself, which means more freedom to set up things the way you like it but also more work and required knowledge to do it properly.

Hardware performance

importance: high
If you need to do one single thing to speed up performance of a typical web site or application, it would be to use SSD (Solid State Drive) for storage, especially for database.

A lot of server side performance of Web applications and PHP applications in particular comes down to the speed of retrieving a data from a database.

Second to having all your data in RAM, SSD would significantly decrease the time your script need to retrieve data and then generate HTML. Whenever possible, go for SSD storage.

Host your website close to your visitors

importance: medium
If you host in United States and a visitor comes from Europe, it adds up at least 0.2s of additional latency for every request. It may not sound like a big deal, but one would spend a lot of time trying to squeeze 0.2s from a php application or a database. That’s why big players like Google maintain network of servers on all continents.

Use CDN (Content Delivery Network) for static assets

importance: high
While only big guys have resources needed to completely distribute their websites geographically, CDNs are available to anyone at really low price. CDN is a buzzword describing a distributed network of servers which makes it easier to host and deliver static resources like JS, images or CSS from a server geographically close to visitors.

CDN will fetch a file from your site, cache it and on a subsequent request, deliver it to visitors from an edge location located as close to a visitor as possible. Major CDN players like Akamai or Amazon (CloudFront) maintain servers on all continents and all major internet hubs. There is a whole CDN plugin category to help you with setup. Using a CDN is a low hanging fruit performance-wise so you should probably do it.

Assess your hosting performance

importance: high
To be able to optimize performance, you need to know what are you working with. You need to get a sense of how your website operates under various load, times of a day. Is it slow all the time or just once it reach a certain load? Is any particular section of your site slower than others?

Getting as much information as possible will help you define bottlenecks and act properly. Use "ab" stress test tool, log in to console and use linux “top” command to get a sense of what’s happening.

Stress test your site with ab

importance: medium
There’s a small Linux utility called “ab” which help you to assess the performance of your current setup.

You point it to your site address, configure a number of total and concurrent requests you want to test with and it gives you a report on average time it takes for a request to finish. After couple of runs you’ll get a pretty good picture of performance of your site as well as your hosting.

Linux top command

importance: medium
TOP is a simple yet really useful command to see what's happening with your server at the time. Most important metric you’re looking for is “load average”, it should stay less than 1. It’s tolerable to see value of 2-5 on traffic spikes or busy hours and anything larger than that means you should get yourself a faster server.

Second metric is CPU, which, obviously, tells you about a current CPU usage (in percentage). And a third really important metric is "IOWAIT", which you for most cases can interpret as a hard drive utilization. The larger IOWAIT is, the more load your hard drive currently handling. Except those 3 metrics, there’re tons of other performance-related information you can get from this single command.

Serve your static assets from a cookieless domain

importance: low
In every request your browser makes are also included all cookies you have set on that domain. For example, a browser request for a photo on http://example.com/wp-content/logo.gif will also include your authentification (and all other!) cookies you have on that domain, even if they’re probably irrelevant for that request.

Cookies are small, but number of http requests per page usually aren’t so it all adds up to a substantial data your browser have to download and process. So it’s a good choice to set cookies to be valid only where you need them (do not set cookies to be valid on *.example.com when you usually need them only on www.example.com) and to host static assets on (sub)domains you have no cookies on.

Google, for example, deliver it’s static resources from gstatic.com domain preciselly for this reason.

Ideally, make size of a HTTP request below 1500 bytes

importance: low
If you keep request header below 1500 bytes, there’s a good chance a request will travel over the wire as a single TCP/IP packet. Request’s URL, cookies and browser headers are all included in a size of the request.

Keep your cookies small and URLs short and load static assets from cookieless domain.

Put all your data in RAM

importance: high
Performance optimization is much easier if you can fit all your hot (ie. active) data in memory, so server would be able to fetch it and deliver without touching a slow hard drive.

This is especially true for databases – so as a rule of thumb, you should have enough memory (and properly configured MySQL ) to fit your whole wordpress database into RAM. This is a link with a couple of ways to see how large is your database

Enable gzip/deflate compression

importance: high
Most of shared web hosts have this already enabled in their default setups but it’s worth to check if your HTML, JS and CSS are delivered compressed to your website visitors.

HTML, JS and CSS are all text so they can be compressed up to one tenth of its original site. Lesser the size, lesser the time is needed for a visitor to receive a page or a script.

Webserver (NGINX vs Apache)

importance: medium
Apache is a default choice for web servers since forever, especially for PHP sites. Most of the wordpress sites around running on Apache. But in the last 5 years NGINX gained a lot of mindshare among performance-conscious folks.

It’s safe to say NGINX is faster and it will be able to serve more visitors on the same hardware comparing to Apache, especially for static content. NGINX is a bit harder to configure correctly but amount of attention it received recently means it’s not hard to find really good tutorials like this one.

Opcode cache (by default on PHP 5.5+)

importance: high
Opcode cache is a mechanism where PHP engine caches compiled version of a PHP script so it doesn’t need to compile it before execution. Compiling to executable code takes time, so using opcode cache is a cheap way to increase speed of PHP code execution.

Opcode caching is enabled by default on php 5.5 and later. For older versions, you’d have to set it up manually. Here’s a how to check if PHP opcache is enabled. And here’s a tutorial on how to set up caching manually.

Enable keepalive

importance: high
“keep alive” is an instruction which tells a web server not to create a new connection for every request. If keepalive is enabled, the server will send multiple files through a single connection. Because creating new connections takes time, using keepalive amounts to a substantial speed boost.

Most of web hosts have this already enabled, but it’s worth a check if that’s also true with your host. With this online tool you can check if your site already supports keep alive. Just enter your web site’s address and look for "Connection: keep-alive" in response headers. And here’s a tutorial on enabling "keep alive" both for NGIX and Apache.

Move session storage from disk to memcache

importance: low
This might benefit you only if you have really high traffic site. PHP keeps one file per every active session on your site. If you have a lot of sessions and/or a lot data per session, PHP could spend a lot of time writing and reading from and to those session files.

But if you tell PHP to keep sessions in RAM data store such as memcache, you’ll get all benefits of sessions without downside of a slow hard drive.

Turn off PHP sessions

importance: low
Parsing session files for each request add some overhead, however small it might be. WordPress itself does not need sessions to function properly but a lot of wordplugins does. So we suggest you to check your setup before disabling sessions in php.ini file.

Use HHVM

importance: low
HHVM is a facebook implementation of PHP application server. It’s considered much faster than running PHP as an Apache module or as a PHP-FPM server. That speed comes with some limitations, most important being the limit of what PHP extensions you can use.

You’ll need a dedicated server or VPS to utilize it as well as a bit of advanced linux knowledge to set it up correctly. Here’s the tutorial on HHVM setup and list of supported [PHP extensions][hhvm-e]

Measure your TTFB

importance: low
TTFB (Time To First By) measures a duration from a user making an HTTP request to the first byte being received by the browser. To put it simply, the higher TTFB is, the slower your website is.

Use PHP-FPM

importance: medium
There are two major ways to run PHP nowadays. First one is Apache’s mod_php, which embeds PHP into the Apache binary and PHP-FPM which run PHP in a separate process which then talks to any compatible web server .

PHP-FPM is considered to be more flexible regarding tuning and performance, which comes with a more complicated setup. Apache/mod_php is a default on most web hosts, with much more support on internet and is generally easier to start with. Our opinion is that PHP-FPM is worth trying if you plan to ditch Apache completely, and utilize lighter and faster web server such a NGINX.

If you have Linux skills and considering moving from Apache, PHP-FPM is the way to go.

Utilize browser caching: expire headers

importance: high
Fastest HTTP request is one never made. You should make sure visitors cache all rarely changed and often used static content. This especially important if you have a lot of returning visitors. If web server is configured properly, a visitor will download CSS, JS, logos, etc only once and load them from cache the next time.

Most common way to do it is to set expire headers for static assets. When a browser see an expire header, it will store and reuse an asset until the date defined in the header. For never changed content such as images, it’s safe to set expire headers far in future, usually couple of years. Of course there’s a plugin to help you with the task.

Enable slow log for PHP-FPM

importance: low
If you run PHP via PHP-FPM is really useful if you could see how much it takes for a particular script to execute. There are two entries in php-fpm config related to logging slow scripts.

First, “slowlog” defines a file where you want slow request to be logged and another, “request_slowlog_timeout” defines for how long a script should run before being considered as slow. Generally, you should log and inspect any script running longer than 1s. For more information, there’s a tutorial on how to enable slowlog

Apache: disable modules you don't need

importance: low
Apache comes with bunch of modules enabled by default. You should examine your apache config for LoadModule statement and disable ones you don't need. While it depends on your particular setup, most of the wordpress sites need only following LoadModule directives:

LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so  
LoadModule expires_module modules/mod_expires.so  
LoadModule deflate_module modules/mod_deflate.so  
LoadModule headers_module modules/mod_headers.so  
LoadModule setenvif_module modules/mod_setenvif.so  
LoadModule mime_module modules/mod_mime.so  
LoadModule autoindex_module modules/mod_autoindex.so  
LoadModule dir_module modules/mod_dir.so  
LoadModule alias_module modules/mod_alias.so  
LoadModule rewrite_module modules/mod_rewrite.so  

Apache StartServer, MaxClients and such

importance: medium
MaxClients directive tells us how many simultaneous connections Apache can handle. Approximately, this is the number of visitors currently using your site. Default value is 256. This directive also has a lot of to do with amount of memory available.

Each connection has it’s own PHP instance which might be 100-200MB large, so you need to balance between available memory and number of simultaneous clients. If Apache hits MaxClients limit, each new visitor is going to wait until free Apache process become available.

MaxRequestsPerChild tells us how many requests one apache process will handle before it dies. It should be a number large enough, like 4000.

KeepAliveTimeout tells apache how many seconds a process should wait for subsequent request on the same connections. Larger the number, the more processes will be in idle state, waiting for requests and wasting memory. 15 seconds should be correct value for most of use cases. If you set this too low Apache will waste time creating and killing processes.

Check for PHP memory consumption

importance: low
This plugin check and display PHP memory usage in admin dashboard. Every active visitor on your site run it’s own PHP instance which means you need to have enough memory to support them. To lower PHP memory footprint, it might be helpful to disable PHP extensions you don’t need.

Check php.ini file for an “extension” instruction and comment out those you don’t use. But keep in mind that various plugins might need various extensions to operate correctly. Most of them will return an error if they can’t find a required extension, so that also might help you narrow down what to disable and what not.

Make sure your hosting run at least PHP 5.4

importance: low
PHP 5.4 brings various improvements over earlier versions, notably lower memory consumption. You should keep PHP updated on last stable version and if that’s not possible, at least try not to use PHP earlier than 5.4.

Cache PHP-FPM responses in NGINX

importance: medium
If you for some reason don’t want to implement caching at a wordpress level, it’s possible to cache responses from PHP-FPM engine at a NGINX level. Setup is quite straightforward – with only one caveat: it’s important to define exceptions carefully so you don’t cache things like member pages, POST requests and such.

Use .htaccess only when there’s no other way

importance: low
.htaccess is a way to inject custom Apache configuration per directory basis. It’s sometimes only way to customize Apache when you don’t have access to Apache server configuration.

Because Apache needs to look for .htaccess file on every request, it adds additional load on hard drive so one should use it only when it’s impossible to achieve needed functionality in other, more performant way. It’s suggested to customize Apache using a server config file instead and then set config parameter AllowOverride to None to disable .htaccess.

Use CloudFlare

importance: medium
Cloudflare is battery included CDN which is free for smaller sites. They offer a lot in their free plan with well documented setup.

Log slow queries

importance: medium
There's a way to log slow MySQL queries. You need to edit my.cnf file and add following directives:

long_query_time=1 log-slow-queries=/var/log/mysql/log-slow-queries.log

After MySQL restart, you'll see any query taking longer than 1s to execute in the log file.

Use MySQL EXPLAIN

importance: medium

MySQL EXPLAIN command is helpful to profile slow SQL queries. If you run

EXPLAIN slow-query

you'll see a report on how MySQL execute the query, how much rows it needs to fetch before returning a result. Documentation on EXPLAIN is quite large and honestly it takes some experience and knowledge to interpret results correctly.

Delete trash, drafts, pingbacks and other unneeded stuff

importance: low
Keep your database lean and remove anything you don’t need anymore, especially if you use MyISAM storage engine. You don’t need to be too pedantic on this, just make sure you don’t keep thousands unneeded rows in your database.

Database storage engine (MyISAM vs InnoDB)

importance: low
MySQL can store data using a lot of different storage engines but you probably using either MyISAM or InnoDB. As a rule of thumb, the largest your dataset is (say, over 1GB), the more sense it makes to use InnoDB.

InnoDB is generally faster, better handle data corruption, works better under high load but it’s harder to backup and does not support full-text searching. And which storage engine a database use is a decision you make per-table basis so you can mix them the way you see fit.

Use tmpfs for MySQL temporary table

importance: low
Complex or unoptimized MySQL queries often force a database engine to create temporary tables for ordering and sorting data.

Touching a hard drive is slow and beside rewriting queries for speed, it’s helpful to tell MySQL (via tmpdir my.cnf directive) to create temporary tables on fast, in-memory storage.

Path to tmpfs vary on each Linux distributions but it’s usually located somewhere under /var directory.

Frequently optimize MySQL tables

importance: low
If you use MyISAM and often delete a lot of data from a database, it’s a smart move to optimize MySQL tables from time to time to make sure an often-accessed rows are placed close one to another.

Tools for monitoring MySQL performance (mytop, show processlist)

importance: medium
Similar to linux top command which is simple yet powerful Linux command to see current load of a linux server, there’s top-inspired command line tool that do the same thing, only for MySQL server.

Unlike top – mytop is not included by default in popular linux distributions so you’d have to install it by yourself. Or just run SHOW PROCESSLIST query and see currently running SQL queries.

Check databases size

importance: low
Check the size of your databases to get a rough idea about how much memory you need to allocate to MySQL.

Ideally, you should have enough RAM to accommodate all hot data in RAM. Easiest way to see how big are your databases are is PHPMyAdmin, a MySQL client written in PHP and available by default on most web hosts.

There’s much more you can do with this tool, like run queries, browse tables, backup and create databases and so on.

Tune MySQL config params

importance: medium
Two the most important my.conf directives probably are key_buffer_size for MyISAM tables and innodb_buffer_pool_size for InnoDB tables, and both, roughly speaking, tells a database server how much memory it has available for caching often accessed data.

This number should always be smaller than size of available RAM (90% of RAM tops) and you need to further lower it down based on other things running on the server (PHP, webserver…)

Pick a light wordpress theme

importance: medium
Don’t use bloated themes.

Yes, we all like attractive backgrounds and nice graphics but generally eye candy comes with a cost of slower loading. For portfolio or photo sites it might be justified to sacrifice a bit of performance for a “wow” effect, but if you’re selling stuff online, you have to trade carefully.

Before using a theme you should use browser dev tools to compare loading time between stock theme and one of your choice.

Profile wordpress plugins for performance

importance: high
WordPress plugins are often the worst performance offenders. Luckily, P3-profiler is a plugin you can use to analyze active plugins and to see how big is a performance toll any plugin put on your wordpress setup.

With nice graph and good reporting, this is definitely a tool every site owner should have in it’s wordpress toolbox.

Selectively enable plugins per post or page

importance: low
Once you analyzed plugins performance with P3-profiler, you could examine if you could improve plugin loading time possibility if you configure WordPress to load only required plugins for any page or a post type.

Plugin organizer is, well, a WordPress plugin which enables you to customize order of plugin loading with a feature to load only certain plugins for certain pages or post types. If you use a lot of plugins, we strongly suggest to check if you can disable some of them this way.

Functions to get a page generation time and number of queries

importance: low
This simple addition to footer.php file of your current theme will print number of database queries and time a page took to generate.

This is probably the simplest way to get an idea of how much time your server need to generate any page.

<?php echo get_num_queries(); ?> queries in <?php timer_stop(1); ?> seconds.

Replace php with static HTML where possible

importance: low
Nothing is as fast as a plain HTML. Once you have to use PHP and database to generate a page, performance drops. So, the ingenious idea here is not to use database or PHP where you don’t need them.

Create and upload html files for rarely changed pages and escape WordPress altogether.

Implement a mobile or responsive theme

importance: medium
Avoid serving a desktop theme to mobile users. With a responsive theme you’ll enhance usability for mobile visitors, help your SEO, and you’ll also have an easier job to optimize static assets, especially images, for mobile visitors.

Beware of backup plugins

importance: medium
Keep a watch on your backup plugins. If you don’t have have any working and tested backup solution, you should definitely think about implementing one.

But the backup, especially for larger sites, is a computing intensive process and during an active backup your site can get sluggish. Make sure you schedule backups to run on the least busy time of a day.

Set charset in HTTP response headers

importance: low
Some browsers will render p age a bit slower if you don't include a character set in a response headers. To avoid this behaviour you need to make sure your response headers contains a line like this:

Content-Type: text/html; charset=UTF-8

You can do it on a webserver level or even on a wordpress level.

Caching solutions

importance: high
There’s a couple of approaches to caching in WordPress. First of all, you could employ NGINX as a reverse proxy and cache PHP-FPM responses.

Second, you could use a plugin to generate and serve static content for often accessed and rarely changed pages or posts.

Third, you could and should utilize a browser cache for static resources like JS, CSS and images. And forth, you can use services like CloudFlare (free for small sites) that do all or some of this for you.

Keep your wordpress updated

importance: medium
It’s an obvious tip but it’s worth to upgrade WordPress to latest version and benefit from all performance and security fixes each new version brings. Before upgrade, make sure your themes and plugins are supporting the new version.

Optimize images

importance: high
If possible don’t load images larger than neccessary. Unfortunatelly, a lot of times it just isn’t feasible to resize images to all different sizes for all different devices and resolutions but what you can do is to learn how you save images optimized for web in image editing tools such as Photoshop.

With this plugin, you can automatically strip unnecessary metadata to make them smaller without sacrificing quality.

Specify image dimensions

importance: medium
Whenever possible, specify image dimensions in HTML code. That will enable browser to reserve screen estate as soon as it parses a page and before an image is downloaded plus it wouldn’t have to calculate dimensions of a image before painting the page.

Responsive images

importance: medium
There’s no point to let slow mobile devices to download high-res photos from your photo site. This is a great tutorial on responsive images and as most wordpress tutorials around it comes with a plugin.

Lazy load images

importance: medium
For a longer, graphics intensive pages it makes sense to use javascript to lazy load images when they enter the viewport. It will lower a page memory consumption, which is especially important for memory-constrained mobile devices.

Combine Javascript into a single file

importance: medium
For most use cases it makes more sense to combine all required Javascript code and libraries into a single JS file, than to download every of them separately.

Time to download a single JS file would probably be lower than time needed to initiate multiple HTTP requests for smaller files. Whatever you chose, make sure you serve JS gzip compressed!

Remove render-blocking JS in above the fold content

importance: high
You should inline JS required for page render and defer loading of remaining scripts, by using “async” attribute or by putting script tags at the end of a HTML document.

Minify JS

importance: low
There’s no valid reason not to minify your JS and further reduce it’s size by couple of percents. The same goes for HTML and CSS too!

Minified JS is much harder to read, but you can address that with sourcemaps or by delivering non-minified code in your development setup. Make sure you also deliver Javascript compressed!

Use async for adsense, analytics and advertisement code

importance: low
Use async loading for analytics, ads and other similar code. Otherwise, browser will block rendering until it loads and execute said code before moving down with parsing a page.

If you embed a lot of external code, this can get pretty slow plus it can effectively shut down your site if any external code fails to load.

Consider replacing default social media buttons

importance: medium
While we all need shares and mentions on popular social networks, a code for embeding social buttons are often slow and bloated.

Consider replacing them with simple icon with links to social network sharing URLs. This is a good plugin to help you create such icons.

Defer JS

importance: high
If you embed javascript code like this (note the "async" param)

<script async
  type=text/javascript 
  src="http://example.org/path/to/file.js">
</script>

browser will not wait for the script to download before moving down with parsing and rendering the page. This significantly increases a perceived speed with one important downside:

There will be this small timeframe during which the page will be visible but Javascript code won’t be ready yet. Which means any interaction dependant on Javascript won’t work until Javascript is fetched and parsed.

We strongly advise you to try this approach because it’s easy to implement and offer huge performance benefits.

Inline critical JS, async load the rest

importance: low
You can additionally improve on previous tip by splitting your single big JS file in two.

The first one should contain only code necessary for an initial page render. Instead of serving it in separate file and wasting a http request, you should inline that code directly intag.

Rest of the code just load asynchronously as described previously.

Load only what you really need

importance: low
It’s possible in WordPress to load only certain scripts on certain pages. Frankly, it requires you to dig down deep in your theme/template but sometimes it's feasible to do it.

This approach use wordpress wp_enqueue_script function which enables you to programmatically (de)register a Javascript file in wordpress engine.

If you aren’t sure in your PHP skills, maybe this might be overkill for you, but anyway, a relevant documentation on the wordpress site is quite good.

importance: medium
Google host most of the popular javascript libraries like jQuery and it's probaby a better idea to link to google's version of a librabry than hosting it yourself.

Not only google servers are probably faster and distributed but there’s also a good chance a visitor will already have google’s version of the popular library cached which means you'll be able to avoid any download at all.

Minimize a number of HTTP requests

importance: high
This tutorial contains a lot of tips but they all comes down to the one simple rule: HTTP request is a performance-expensive operation. Don’t request what you don’t need!.

Cache, reduce, then reduce some more!

Measure performance

important: high
There’re numbers of free tools available to measure a website performance but for most practical purposes, you need just two of them:

Browser development tools, where you can analyze every request and how much it takes to complete and google pagespeed tool, where you can test any page and get a score with suggestions on what to improve.

Check us out, we got 98/100.

Remove query strings from statics assets

importance: low
Avoid query strings for images, scripts and CSS. If you link a static assets like this <img src="/path/to/image.jpg?query=string" /> some browser might not cache it at all.

If that’s not your intention (and there are legitimate use cases where you need to disable browser caching), you should remove query strings from static assets.

Use subdomains to avoid browser connection limit

importance: medium
A typical browser can open and use just so many connections (up to 8 and often less) simultaneously. If a page have, say, 50 images, browser will be able to download only 8 images at the time.

To avoid waiting for a free connection, you can distribute assets on multiple subdomains (static1.example.com, static2.example.com… all of them pointing to the same place) instead a just one, because connection limit is applied per (sub)domain level.

If you divide your images on 3 subdomains, a browser will be able to download up to 3×8=24 files simultaneously. However, every new domain brings additional overhead of DNS lookup, so, don’t over optimize on this one.

Use iframe widgets carefully

importance: medium
External iframe widgets such as Facebook, Disqus and the like will inevitably slow down your page. While they offer value, you need to use them carefully, keeping in mind that a most of embeds will effectively make your site unusable if they go down and fail to load.

Style action buttons appropriately

importance: medium
You should always style your action buttons to react on clicks, hovers and such. While it might look obvious, a perceived performance is as much important as an actual one.

When your UI response instantly to an interaction, even if it’s just a simple button color change, you work with and not against our mental expectation of things to react when we play with them.

Add progressbar and/or use optimistic updates

importance: medium
You can do a lot to improve perceived performance if you make your UI react instantly to user’s interaction. You usually don’t have to wait for a server response before increasing a counter or before displaying a comment after submit.

It’s called "optimistic update" when you render an update immediately and wait for a server confirmation in the background. If that approach is not possible for some reason or user have to wait more than a second, at least render progress bar or status bar immediately.

Optimize delivery of above the fold content

importance: medium
Above the fold content is what a visitor see in the first browser screen. When you design and optimize a site, you should make sure this most crucial part of user experience is as fast as possible. Make sure you avoid Javascript or CSS blocking in the above the fold content.

Don’t use 301 redirects if not necessary

importance: low
301 redirect is a SEO friendly way to move a page from one URL to another. It adds up an additional HTTP request so make sure you update your code to use new URLs leaving 301 only for things you have no control over (like, to keep old external links working).

Make redirect cacheable (302 with lifetime)

importance: low
If you have a mobile subdomain (like m.example.com) you probably somewhere in your code redirect a visitor to the mobile version. Make sure you do it with 302 redirect which is cacheable.

Reduce the number of third party assets

importance: medium
Use network tab in your favorite browser dev tool to see all resources required by a page, sortable by a domain name. Then examine if there’s anything you can remove or disable. This is also the easiest way to remove a bloat from a theme.

Reduce the size of HTML code

importance: low
It’s possible to remove spaces, tabs and newlines from a HTML code to reduce it’s size. This is a quite modest improvement but this plugin makes it really easy so why not. You should also minify your CSS and JS files.

DNS prefetch

importance: low
If a HTML page loads resources from a lot of different domains, it might be beneficial to tell the browser to resolve those domains as soon as possible to shave a few additional milliseconds of delay.

For most use cases, this brings very little value, but sometimes it might be of use.

<link rel="dns-prefetch" href="//www.domain1.com"> 
<link rel="dns-prefetch" href="//www.domain2.com">

Setup a local development environment to easier test changes

importance: high
Create a development wordpress environment on your local machine so you can test and measure changes before pushing them into production.

Official wordpress docs have a good resource page on setting up a local wordpress environment both for Mac and Windows.

Get familiar with Linux!

importance: low
There’s a good chance your hosting provider using Linux as an underlying operating system. Basic Linux knowledge is a must for any serious work on performance optimization.

If you’re not ready to make Linux your main operating system, you can utilize virtualization to run Linux along your main OS, be it Windows or MacOS.

Use a good DNS provider with anycast support

importance: high
Use good DNS service for your domain! Slow DNS adds an dditional latency, not to mention your site can become unavailable if it's DNS hosting provider goes down.

Amazon’s Route53 is robust, fast and cheap solution for DNS hosting. Anycast support means a visitor's DNS requested is always routed to the closest server, which reduces DNS resolve latency.

Get familiar with browser developer tools

importance: high
Browser development tools are something you use every day as a web developer. They offer various ways to test, debug and analyze everything from a web page performance, client memory consumption, JS execution and debugging, cookies manipulations and so on. Every major browser has it’s own developer tools.

Chrome dev tools

Chrome is probably the best browser around for a developers precisely because it’s dev tools are unbeatable. Dev tools are included by default in Chrome (launch it with CTRL+Shift+C).

Firebug for Firefox

Firebug is the oldest browser dev tool around and is still go-to choice for Firefox developers. Virtually all other browsers borrowed ideas and UI for their dev tools from Firebug. Unfortunatelly, it’s still available only for Firefox.

Safari dev tools

To launch Safari dev tools, you first need to enable it. The complete documentation on using it is here.

IE dev tools

IE since version 8 also includes developer tools, called F12. You can launch it with, well, F12. Documentation

Avoid CSS import url instruction

importance: high
CSS import url instruction is used to import another CSS file into the current one.

You probably shouldn’t use it because it prevents browser from downloading CSS files separately – browser will stop downloading the current CSS file until it resolves and complete import instruction. Use <link> tag instead.

Remove a CSS bloat

importance: low
Most of CSS and JS UI frameworks have quite large default CSS files. Make sure you use only what you need and remove CSS for components you don’t use.

Minify CSS

importance: low
Just as with JS and HTML, strip unneeded characters from CSS files too. This plugin can help you with that.

importance: medium
Instead of this:

<link rel="stylesheet" type="text/css"
      href="http://fonts.googleapis.com/css?family=Droid+Sans">
 <link rel="stylesheet" type="text/css"
       href="http://fonts.googleapis.com/css?family=Lobster">

use this:

 <link rel="stylesheet" type="text/css"
       href="http://fonts.googleapis.com/css?family=Droid +Sans|Lobster">

Inline Google Fonts API CSS

importance: low
Instead of this:

<link rel="stylesheet" type="text/css"
      href="http://fonts.googleapis.com/css?family=Droid+Sans">

rather download the font CSS from the link statement’s href, paste it in your CSS file and save yourself a HTTP request

@font-face {
  font-family: 'Droid Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Droid Sans'), local('DroidSans'),
  url(http://fonts.gstatic.com/s/droidsans/v6/s-BiyweUPV0v-yRb-cjciC3USBnSvpkopQaUR-2r7iU.ttf)
  format('truetype');
}

Use Base64 for small static assets

importance: low
Small assets such as icons and logos are probably load faster if you inline them in directly in CSS. There’s an online tool to encode images with Base64, a textual representation of binary files compatible with CSS.

Use CSS sprites where possible

importance: medium
If you use a lot of icons, you shouldn’t reference them separately in HTML or CSS. Rather put them all in a single sprite image and save a number of HTTP requests.

True, this gives you additional responsibility for maintaining a sprite, but with this tool a hassle should be minimal.

Use font icons instead of images where possible

importance: low
Different devices with different pixel densities means you have to maintain at least two sizes for every icon – one for retina displays and one for regular.
Well, not if you create a font file and keep your icons there. This approach enables you to have a single icon version for all resolutions and displays and resize them in CSS just like you would do with any text.

Interested? Fontello is a great online tool to get you started.

Use CSS for effects and transitions

importance: medium
If you can achieve something both with CSS and JS, it’s probably a better idea to do it in CSS.

This is especially true for visual effects because CSS often offloads animations and transitions to device’s GPU acceleration unit which makes them much faster than anything you can do in JS.

Use CSS instead of images for shadows and gradients

importance: low
CSS has a pretty good support for shadows and gradients. If you really don’t have to, don’t make them as images. CSS can do the same job, especially for simple shadows and gradients, much faster and better.

Reduce fonts size with Fontforge

importance: low
Don’t include the whole font if you need it only for couple of characters. Use font icons instead or remove unneeded symbols (glyphs) from a font with FontForge.

Inline above-the-fold CSS

importance: low
We already mentioned importance of above the fold content in a perceived page performance. If you inline above the fold CSS directly in HTML, you’ll make sure a visitor get this most important part of a page as soon as possible. And yes, there are tools for that.

Defer CSS loading

importance: medium
If you inline CSS used at above-the-fold content, it's easy to defer rest of the CSS with a little bit of JS. That way you get the best of both worlds – have above the fold content rendered as fast as possible and avoid blocking which happens when you load CSS from HTML HEAD tag.

This is an example JS code for CSS deferring.

<script type="text/javascript">
  var stylesheet = document.createElement('link');           
  stylesheet.href = 'style.css';           
  stylesheet.rel = 'stylesheet';          
  stylesheet.type = 'text/css';
  document.getElementsByTagName('head')[0].appendChild(stylesheet);     
</script>

Combine CSS into a single file

importance: medium
Most of the time it’s faster to load a single combined CSS (or JS) file than a lot of smaller ones.

But the thing is – not all the time. There is more than one plugin to help you combine your CSS files into a single one, but before you use any of them, you should measure if this technique brings any value for your particular site.

How? Use your browser’s development tools.

Inline your fonts and avoid FOUC

importance: low
Sometimes it’s reasonable to download fonts and put them in the CSS file or even inline directly in HTML. Inlining CSS (with or without fonts) is only way to avoid a "flash of unstyled content", often saw phenomena when browser render a HTML page before CSS finished downloading.

You made it to the end!

Congratulations! Drop us a line if you think we forgot to mention something important in the list or if you'd like us to take a look at performance of your wordpress site.