WordPress speed up and optimization - Adame Dahmani
WordPress speed up and optimization

WordPress speed up and optimization

I explore all realistic ways to make WordPress the fastest possible, ranging from easy performance enhancements to nerdy tweaks :)

WordPress is without a doubt one of the best website-building platforms available.

It’s very flexible, offers a tremendous number of themes and plugins for pretty much everything, is quite budget-friendly, and is backed up by fantastic page builders and cutting-edge SEO frameworks.

It will take some effort to get it up to speed.

We’ll go over all of the realistic performance-boosting techniques for WordPress here.

Super Important

There is no magic:) if you want your website to run at its best, you must be willing to do a few things. Mainly:

  • Make an effort to use the suggested approaches.
  • Develop your skills so that you can perform complex optimizations.
  • Invest in tools that assist you in completing the task.
  • If progressing to the next level of improvements proves difficult, seek professional assistance.

The following are a few things that could help you improve your performance and grades:

  • To fix specific performance concerns, accommodate/change some code.
  • If the current themes/plugins can’t be modified to improve performance, consider switching.
  • Add a Content Delivery Network (CDN) to the mix.
  • If there is actual evidence that hosting, CDN, or DNS services are negatively impacting the site’s performance, consider changing them.

Without further ado, I’ll hand it on to you :)

This is where your WordPress speed and performance journey begins!

Why you should care about your WordPress website speed?

#

Typical WordPress Website

#

WordPress itself is not slow.

In general, the more code you add, the slow WordPress will be. Efficient code will surely help reduce the impact but it won’t at 100% prevent it.

Reaching the final website we picture in our minds, with top-notch design, and a plethora of features, might come at a performance cost.

Most WordPress users turn to themes, page builders, plugins, sometimes using code snippets or fully coded features, as well as adding a bunch of 3rd party scripts to make it happen.

Each plugin we add, each feature, tracker we think we need will have its toll on the website’s speed.

The potential speed decrease applies to both the frontend (what your visitors see) and the backend (the dashboard you use to manage the website.)

Why?

  • We usually get more than what we need in terms of features and codebase.
  • We have different codes from different developers interacting and possibly conflicting.
  • Some themes and plugins are poorly coded and deliver poor performance.

And it doesn’t stop there. Things get even more complicated.

When we need to pick assets and services for our website, we mainly base our decision on the pricing rather than what will help to get the job done properly without hurting performance.

Most of us are guilty of:

  • Going cheap on hosting.
  • Picking lower grade themes and plugins and slower 3rd party services to spare some money.
  • Doing technical stuff ourselves without the right knowledge. Just to avoid hiring pricey qualified labor.

Performance-wise, it usually ends up pretty bad.

Speed matters, and here is why

#

WordPress adopters tend to overlook the speed effect.

The funny part is, there are plenty of clues suggesting that loading speed is just as important for a website as the design and the content.

Here are a few:

  • Speed is crucial to avoid visitors’ early exits.
  • Speed is vital for conversions.
  • Speed is a ranking factor for search engines.
  • Speed is a must-have for mobile visitors and even more critical when using cellular networks.

The above is not a guess. This is what we learn from working on WordPress performance for the last decade up until now.

A bit of history

It started with the AMP release in 2016. Google wants to make mobile load pages fast.

AMP (originally an acronym for Accelerated Mobile Pages) is an open source HTML framework developed by the AMP Open Source Project. It was originally created by Google as a competitor to Facebook Instant Articles and Apple News. AMP is optimised for mobile web browsing and intended to help webpages load faster. AMP pages may be cached by a CDN, such as Microsoft Bing or Cloudflare’s AMP caches, which allows pages to be served more quickly.

Wikipedia – Accelerated Mobile Pages

Google AMP has a low footprint page structure and above all, is cached by Google’s own CDNs, or other CDN providers like Cloudflare.

Google confirmed in 2018 that “speed” is a ranking factor for both Google Mobile Search and Ads and they use PageSpeed Insights, which is based on their Lighthouse auditing tool, to test pages against multiple criteria and that make a score.

Their benchmarking, based on a 2017 study, has some interesting figures.

How speed and bounce rate correlate

  • 1s to 3s has a probability of a bounce increase of 32%.
  • 3s to 5s has a probability of a bounce increase of 90%.
  • 5s to 6s has a probability of a bounce increase of 106%.
  • 6s to 10s has a probability of a bounce increase of 123%.

Other best practices indexes

  • TTFB on mobile is judged good under 1.3s.
  • Requests need to be less than 50 requests per page.
  • And page size needs to be less than 500kb.

Speed as a ranking factor for desktop

One last for the road before we start talking WordPress speeding up fundamentals and actionable plans.

Speed always had its weight on ranking, but we didn’t know how Google evaluates it.

We now know.

On one of Google Webmasters Q&A sessions, also known as #AskGoogleWebmasters, Martin Splitt, Webmasters Trend Analyst at Google, answered a couple of questions about loading speed and SEO.

One question, in particular, was interesting.

It was about how Google calculates speed when it comes to ranking.

And here is the answer:

Google uses two sets of speed data when ranking pages:

  • A theoretical speed using lab data.
  • Real field data from real-world users who visit the actual page.

Lab data is a bit tricky, as Google has typical speed for different types of websites and industries.

So, when it comes to ranking, your speed is compared against:

  1. Your competition loading speed.
  2. What Google thinks is the right loading speed for the kind of page you are running.

Google mainly depends on Lighthouse (again) for that.

In November 2019, Google rolled out a “Speed report” on its Search Console.

This time, Google suggests paying attention to page speed on both mobile and desktop by adding separate results for mobile.

The above timeline gives us an idea about how Google is progressively walking toward adopting speed as a significant ranking factor, with PageSpeed Insights as the backbone of it. 

Browsers will start to “shame” websites with low speed

In November 2019, a blog post, published on Chrome development blog, revealed an upcoming feature on Google Chrome browsers that will reward fast websites and penalize slow ones.

A badge, giving insight about how fast the website typically loads, will be shown as the website is loading. 

A bad speed will definitely play a role on early exits. 

There are plenty of studies correlating speed and conversions and user retention. But all of them are just confirming Google’s take on the matter.

Here are some to consider:

Bottom line?

Ultimately it comes down to one thing: Just make sites fast for users (quoting Martin Splitt on that.) and optionally, make Google Lighthouse happy.

You have no excuse but to make your WordPress website blazing fast

#

You might be asking yourself, why should I bother if it’s working for me as it is?

Having a slow website might still work, but it will make things much harder and less effective.

As a web property owner, you need to have performance in mind because every visitor will expect it to load lightning fast. Search engines have similar expectations too.

All technological bottlenecks are improving too:

  • Internet speed is getting faster.
  • Browsers are getting better helping websites with performance (like Google Chrome adding a built-in lazy load feature).
  • Internet upcoming standards will give a considerable boost for speed (HTTP/3 and QUIC).
  • Servers technologies have progressed in a meaningful way (Nginx and LiteSpeed servers, PHP 7+, and the upcoming PHP 8).
  • Even mobile phones have better CPU and RAM.
  • CDN technology covers more regions, with more features focused on improving performance.
  • Caching plugins are getting better.

Everything works on our favor to make websites lightning fast. Which leaves any website underperformance on your camp :)

If your business generates leads and sales online, then you must care about speed even more.

Seriously.

Why?

Like we’ve seen earlier, speed correlates with conversions. But here is a more tangible way to understand it.

Google has a great tool called Test My Website for mobile performance testing. One of its features is a simulator that evaluates the impact of speed over revenue.

Though it’s primarily meant for mobile, it still gives insight about potential losses if you neglect working on your site’s speed.

Speed correlation with revenue increase

Here is an example:

  • Dropping 1s in this simulation resulted in a 9k additional yearly revenue.
  • Dropping 1.5s in this simulation resulted in a 16k additional yearly revenue.
  • Dropping 2s in this simulation resulted in a 26k additional yearly revenue.

Give it a shot yourself! Make a simulation and see what kind of revenue you might gain (or lose) depending on your current speed.

How to test it

Go to Test My Website.

Give it a spin by adding your domain name or your landing page.

Once you see the results, note your mobile loading time.

Click on “Other Tools.”

Scroll down a bit and activate “Evaluate the impact of a faster site” accordion tab.

Document your current speed, average monthly visitors, the conversion rate, and the average order value.

Play around with different speeds and see how much revenue you are missing per year just because of speed.

How to speed up WordPress?

#

Building knowledge around performance

#

Building the right knowledge about websites performance is critical.

It will allow you to know exactly what needs to be improved, why, how, and if the effort is worth the reward.

Ignorance in that matter will undoubtly cost you money and time :)

Knowing better what you are doing will help you set reasonable goals that can be achieved with the means you have in hands.

It will also help focus your energy on improvement venues that will make a meaningful difference and ditch the opposite.

Problem-solving

#

Another vital skill to have :)

You need to be able to identify performance bottlenecks, what is causing them, which can be fixed or at least improved?

Part of the process is to find realistic and applicable solutions. This includes realizing when the problem can’t be solved without going through drastic changes and/or making concessions. And decide what is best.

As you build your knowledge, experience, and skills, performance will be more of a way of thinking rather than gearing up to “patch” whatever you can.

Progressive improvement

#

It’s easy to get lost as there are so many venues to improve WordPress’ performance.

The best way to handle it is to start with low hanging fruits and quick and easy fixes.

This will give you immediate improvement and build your confidence to tackle harder and more complex bottlenecks.

More advanced technique will require time to gain the necessary skills to apply them properly, so, don’t rush it! One step at a time :) And make sure you understand what you are doing.

Building with performance in mind

#

Once basics for websites’ performance acquired, you will start moving from fixing performance issue to building websites performing well out of the box.

This can be achieved by:

  • Picking the right themes, page builders, and plugins to use.
  • Avoiding practices that might hurt performance.
  • Using web services when WordPress options to implement a feature prove to be a performance nightmare.
  • Using quality hosting.

What can be optimized in WordPress?

#

Let’s have a look into how a typical WordPress site responds to a request from browsers.

The request goes to the server, where PHP workers fetch data from the database (using MySQL), to return a response to the browser.

Optimizing WordPress is enhancing the flow and performance from the request to the final response by acting:

  1. At the application level, to adjust the response to comply with user experience and testing tools recommendations and directions and pre-built static pages (page caching).
  2. At the server level, to get a faster response time by using enough resources and a performant stack for a smooth page generation and admin operations, and a better management of repetitive requests (server-side page caching and Object Cache).
  3. And off-server, by surrounding the server and website with technology to help speed up the documents and assets delivery, and a better way to communicate with browsers (DNS and CDN).

An optimized structure will look like:

Before starting to dig in each component, let’s first set our standards by learning how to measure performance, and what to target exactly,

WordPress Performance KPIs

#

User experience metrics and Web Vitals

#

Not so long ago, web site speed was judged solely by the loading time.

I was personnally advocating that as long as it loads fast, it doesn’t really matter what testing tools gave as scores.

With a good reason though: testing tools didn’t give a properly reason to consider their recommendation. Including PageSpeed Insights.

But the game has changed after Google started educating about the importance of considering user experience metrics, and making room for speed and complying with their rules as a ranking factor.

We now have a reason to focus on web vitals, especially the core web vitals, tools to measure it, and a reward to get the audit results to the green side.

I will here present briefly the web vitals, and will include in all possible performance optimization that can be done for WordPress which web vitals are targeted.

First Contentful Paint (FCP) [CORE]

#

First Contentful Paint (FCP) measures the time from navigation to the time when the browser renders the first bit of content from the DOM.

In human words

FCP reflects how long it takes users to start seeing content on the web page.

At this stage, visitors know that the wait time is over and that the page will start to render.

Google PageSpeed location

Performance scale

2.3s
Mobile
4.0s
0.9s
Desktop
1.6s

To learn more

Largest Contentful Paint (LCP) [CORE]

#

The Largest Contentful Paint (LCP) metric reports the render time of the largest content element visible within the viewport.

web.dev

In human words

LCP reflects how much time the user needs to wait to see “usable” content above the fold.

It reflects more the perceived loading speed for the end-user than the actual loading speed. The page loading is still kicking in the background.

This metric is important to decide how to structure content to make the “hero” part of the page load fast.

Google PageSpeed location

Performance scale

2.5s
Mobile
4.0s
1.2s
Desktop
2.4s

To learn more

First Input Delay (FID) [CORE]

#

FID measures the time from when a user first interacts with a page (i.e. when they click a link, tap on a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to begin processing event handlers in response to that interaction.

web.dev

In human words

FID reflects how fast will the page respond to users trying to interact with it.

This metric is important to decide what CSS and JavaScript codes are critical for the first user interaction, and to priorities their loading.

Google PageSpeed location

Performance scale

100ms
Mobile
300ms
100ms
Desktop
300ms

* there is no recommended value for FID as it’s a field metric

To learn more

Time to interactive (TTI)

#

Time to interactive is the amount of time it takes for the page to become fully interactive

In human words

TTI reflects the time needed to make the page “responsive to the user’s actions.”

It’s basically when the visitors see the content and can interact with it.

This metric can be important for highly interactive pages, like a live chat page, for example, or a highly interactive map.

Performance scale

3.8s
Mobile
7.3s
2.5s
Desktop
4.5s

To learn more

Total Blocking Time (TBT)

#

The Total Blocking Time (TBT) metric measures the total amount of time between First Contentful Paint (FCP) and Time to Interactive (TTI) where the main thread was blocked for long enough to prevent input responsiveness.

In human words

TBT reflects the time needed for the web page to be fully ready for the user after they start receiving it [the web page].

This metric helps to see if there is any task that needs a considerable time to execute.

Anything more than 600ms needs a closer look to locate and attempt to enhance the execution time of some components of the website.

Performance scale

0.30s
Mobile
0.60s
0.15s
Desktop
0.35s

To learn more

Speed Index (SI)

#

Speed Index measures how quickly content is visually displayed during page load.

In human words

SI reflects the time needed to populate the page view.

Visitors are able to start reading the content while the loading process is progressing.

This is what users would as the loading time of the page.

Performance scale

3.4s
Mobile
5.8s
1.3s
Desktop
2.3s

To learn more

#

TLS/SSL Handshake

#

TLS handshakes are a series of datagrams, or messages, exchanged by a client and a server. A TLS handshake involves multiple steps, as the client and server exchange the information necessary for completing the handshake and making further conversation possible.

— Cloudflare: What Happens in a TLS Handshake?

Human words

TLS Handshake is how the browser and the server agree on their communication terms. These terms include:

  • Acknowledge each other
  • Verify each other
  • Establish the encryption algorithms they will use
  • Agree on session keys

It is an extensive exchange that happens in a few up to hundreds of milliseconds depending on the TLS protocol used, the encryption level, and the distance between the browser and the server.

Time to First Byte

#

TTFB measures the duration from the user or client making an HTTP request to the first byte of the page being received by the client’s browser.

— Wikipedia: Time to First Byte

Human words

TTFB is the time of a roundtrip between:

  1. Your web browser (sending a request).
  2. To your hosting service (sending a response).
  3. Then back to your browser (receiving the response).

It’s not a full response, though, because TTFB is only calculating the time it takes to get the actual response.

Some speed testing tools refer to it as waiting time, which is a better and non-complicated approach. TTFB is how long it takes for your browser to receive a response to a request.

Time-to-first-byte example

TTFB helps to understand how the app in the server performs, and whether or not the hosting solution we use does its job.

We will spend more time digging into this one.

What makes the TTFB?

The TTFB is usually confused with the sever’s processing time or the page loading speed.

To understand better what counts as part of the TTFB, we need to take a look at a typical “request” journey is a follow.

Typical Request Journey

The TTFB is made up of:

  • Socket connection time (DNS, SSL handshake)
  • Network latency (sending the request)
  • Firewall interception (if any)
  • Server-side processing
  • Network latency (receiving the response)

So, it’s visibly not just about the server-side processing, and it includes the network latency, usually the most time-consuming part.

We will get to know better each one of these with potential fixes to enhance their speed and responsivity.

Another important thing is that TTFB doesn’t reflect the full loading time of a web page.

The full loading time includes:

  • Loading the actual webpage and resources, while TTFB count stops when receiving the first byte of the asset.
  • Loading 3rd party assets.
  • Receiving 3rd party responses.

Carry out ideas/facts

  • TTFB includes the network latency and not just only the server’s processing part
Does it only affect webpages?

When testing TTFB (we’ll get to that soon), we concentrate more on the actual page (referred to as the “document” asset type).

The HTML page has, indeed, the most significant delay in most cases of low TTFB. But that waiting time affects any asset requested and returned by a web server, including:

  • CSS files
  • Fonts
  • Images
  • JavaScript files
  • Videos
  • Ajax requests too

With a slight difference, however.

Static assets don’t need processing and won’t show a noticeable TTFB in most cases. We usually get the same effect for HTML pages, too, when cached or when turned into a static file.

DNS Resolve

#

The Domain Name System (DNS) is a hierarchical and decentralized naming system for computers, services, or other resources connected to the Internet or a private network. It associates various information with domain names assigned to each of the participating entities.

— Wikipedia: Domain Name System

Human words

DNS is what glues your domain name to your web server. It’s basically translating a domain name in a computer-friendly IP address.

DNS lookup is the most expensive part of the process. It involves 8 different steps for the process to complete for each domain name.

DNS look-up example
DNS look-up example

Luckily there are a couple of techniques to cut the steps and speed up the process.

To learn more about it:

Tools to measure WordPress performance

#

We can’t enhance what we can’t measure.

Most WordPress website owners sensible to performance will focus more on getting a 90+ score on Pingdom Tools, or GTMetrix, or Google PageSpeed Insights.

Some voices will say, if WordPress performance and loading speed you are after, then these rounded scores are not a “valid” measurement metric.

Our own take is, yes, speed is the ultimate goal when dedicating time and energy to improve a WordPress website’s speed. But we also need to make sure some specific performance metrics are up to standards.

Focus on meaningful website performance KPIs (key performance indicators) will help getting the best of both worlds (score an actual speed).

Performance tools each have their particularities and usefulness in the WordPress optimization process.

Lighthouse and PageSpeed Insights (must have)

#

What is it?

Lighthouse (Google Chrome DevTools) and PageSpeed Insights web app are tools for web pages auditing.

They are used to test page’s performance, accessibility, SEO, and progressive apps implementation.

Lighthouse is by far the most hated speed testing tool ever. Anyone optimizing WordPress, especially non-professionals, avoid it like the plague.

The thing is, there is no way around it now.

Both tools give an accurate state of your page vs. how Google is expecting it to perform. And it happens to be the tool of choice that Google chooses to audit pages for ranking purposes.

Targeted metrics

  • Web vitals.

Lighthouse is believed to be one the foundation of how Google assesses speed for ranking. The metrics you see on Lighthouse and PSI are how Google sees your page’s performance. Perfecting them means getting the favors of Google.

Testing locations

  • Both tools test against your current location and using your current internet speed.

Important to know about PageSpeed

  • PageSpeed Insights takes into consideration your current test Lighthouse results and field data taken from real visitors of your website.
  • PageSpeed Insights visitors data is an aggregate of 30 days of collected visits data. Meaning, any improvement you’ve done on your site might take up to 30 days to give an accurate performance score.

How to access it?

For Lighthouse

Open Chrome browser.

Open DevTools by clicking the following commands:
Command+Option+C (Mac).
Control+Shift+C (Windows, Linux, Chrome OS).

Click the “Audit Tab” button.

For PageSpeed Insights

Put your link on the designed field.

Click the blue “Analyze” button.

For PageSpeed Insights

Understand the scoring logic

Lighthouse, and PageSpeed to some extent, uses a specific scoring weight for each tested metric:

  • 15% for FCP (First Contentful Paint)
  • 15% for SI (Speed Index)
  • 25% for LCP (Largest Contentful Paint)
  • 15% for TTI (Time to Interactive)
  • 25% for TBT (Total Blocking Time)
  • 5% for CLS (Cumulative Layout Shift)

You can check and experiment with Lighthouse V6 right here.

Learn more about how Lighthouse performance scoring works right here.

GTMetrix (Good for Adblock and mobile testing)

#

What is it?

GTMetrix is an advanced auditing tool. It gives more insights about optimizations, with a better control over the testing environment.

GTMetrix has a couple of interesting options:

  • Control over the browser.
  • Control over the connexion (to simulate different types of Internet access).
  • Possibility to run tests with Adblock Plus enabled (very handy to test speed without ads overhead bias).

 Targeted metrics

  • Loading speed (with waterfall).
  • Number of requests.
  • Better insights about optimizations (minimizing, combination, deferring, and others).

Testing locations

North America

  • Vancouver, CA.
  • Dallas, US.

South America

  • Sao Paulo, BR.

Asia

  • Hong Kong, CN.
  • Mumbai, IN.

Europe

  • London, UK.

Oceania

  • Sydney, AU.

How to access it?

GTMetrix

Create a free account to enable changing options. Otherwise, testing will be locked to the following:

Location: Vancouver, Canada
Browser: Chrome (Desktop)
Connexion: Unthrottled

Put your link on the designed field.

Click the “Advanced Options” to be able to change the testing settings if needed.

Click “Analyse” to start the test.

Important

  • GTMetrix stops the tests after 2s of network inactivity, which might bias the results. It’s best to activate the option “Stop test onload” in the settings.

Pingdom Tools (for quick overview)

#

What is it?

Pingdom tools offer a quick overview of tested websites’ speed on a specific region. It also gives more details about requests.

Very handy for quick diagnoses.

 Targeted metrics

  • Loading speed (with waterfall).
  • Number of requests.

Testing locations

North America

  • San Fransisco, US.
  • Washington D.C, US.

South America

  • Sao Paulo, BR.

Asia

  • Tokyo, JP.

Europe

  • Frankfurt, DE.
  • London, UK.

Oceania

  • Sydney, AU.

How to access it?

Pingdom Tools

Put your link on the designed field.

Pick a location from the drop down list.

Other tools

#

There are, of course, other tools for auditing websites’ performance.

We only mentioned the few that have value for testing/auditing websites for speed.

Here are other popular testing tools for websites performance:

What is penalizing your performance at the application-level?

#

Trying to do everything with plugins

#

Plugins are indeed a convenient way to implement a feature on WordPress.

Sometimes, they fit perfectly on the ecosystem, but other times there are better options, and using a plugin to implement a feature will be more of a burden to WordPress than a solution.

Keep options open. Use better alternatives when they are available, like:

  • Using SaaS products for specific features (we have an extended list few chapters away).
  • Hand code small features.
  • Using server-side features, like security for example.

Bad design and coding

#

Performance is tied to the browser’s timeline event properties.

  • Loading
  • Scripting
  • Rendering
  • Painting
  • as well as other events

The amount and efficiency of the code we add, would it CSS or JavaScript, will impact how fast the browser will interpret it.

It goes without saying that using inefficient techniques and heavy codes will have a negative impact on the website’s performance.

Must have vs. Nice to have

#

Bloat of any kind will always negatively impact how the website performance.

Code-wise, design-wise, feature-wise, the main focus should always be what is really needed to achieve a certain goal vs. adding it just because it will be a nice thing to have.

To name a few, think:

  • Video backgrounds with autoplay above the fold.
  • Heavy JavaScript features, like sliders, session recording, highly interactive codes.
  • Complex layouts that need an extensive CSS to happen.
  • Unnecessary animations.

Multifunction themes and plugins

#

It has been a tendency for the last few years to see themes and plugins with a wide range of features.

The issue with that kind of profile is that the theme, or the plugin, will do a great job with one or two features, while giving a poor expedience and outcome with the rest of it.

It is best to opt of a one-purpose item to gain in efficiency, especially in plugins.

Un-updated themes and plugins

#

Themes and plugins code base evolves with time to provide a better performance.

Developers will always upgrade their assets to include newer versions of libraries, better support for new versions of PHP, more efficient ways to handle the feature, including the interaction with the database, and other performance-focused improvements.

Omitting always be at the latest version of your used assets will make you miss any enhancements pushed by their developers.

Optimizations to speed up WordPress front-end

#

Caching is the key

#

Caching is responsible for the highest performance boost you will get for WordPress.

That cache can happen in several stages of the page delivery.

Knowing these is important to help you find opportunities to serve cache, and also be well equipped to diagnose caching-related issues.

Efficient caching strategies is what makes:

  • Websites handle traffic with no performance issues on a smaller VPS server.
  • Shared hosting services look like capable servers while using a very limited resources allowance per site.

We will explore some notions and a couple of caching levels important for WordPress performance.

What is “website caching”?

#

Simply put, website caching is like responding to a question that you know the answer for.

What happens when you don’t have the answer? Well, you think :) look at books, the Internet, or asked other people, to find the right answer before giving it to whoever asked.

The actual technology behind it can be complex, but in the essence, it is just as described above.

In WordPress realm

Looking for the answer would be the normal page generation route, in short PHP + MySQL, and possibly grabbing data from external sources, to generate an HTML page as a response.

Giving the answer from cache would be saving that response on the hard drive, and serving it as a response instead of going through the whole process to generate the response.

WordPress cache

#

WordPress has a dozen of cache-managing plugins.

From the caching perspective, these plugins handle the following:

  • Catch processed files and store them on the hard drive.
  • Properly set expire headers to fit caching needs.
  • Serve cached files when possible.

Technologies, logic, and efficiency of the system with defer from a plugin to another.

We are fond of WP Rocket! But we also like Swift Performance Pro and LiteSpeed Cache plugins in that particular department.

Server cache

#

The server cache is a built-in system that will create a copy of a page and serves it instead of going through the whole page building process.

All major servers software have their own caching systems:

Setting up a server-side cache is highly technical. It is usually provided as a service on most hosting services and server panels.

Good to know

It is possible to control clearing the server cache using some specific plugins:

Proxy cache

#

Proxies in web hosting context are servers sitting between the user and the provider of web content.

When a visitor tries to access the website, the proxy will respond to requests on behalf of the origin servers.

Example of proxies

  • Content Delivery Networks (CDN).
  • Varnish Cache and Nginx (when used as a reverse proxy).

What do we need them?

  • To lighten the load on servers.
  • To serve static assets from a closer location to the end-user.

How proxy cache works?

A visitor opens a webpage containing static content like images, CSS, and JS files.

Browsers need to request these assets in order to render the page.

If a proxy is set, it will receive these requests and check if it has the requested resource.

If it does, it will check if it’s within the expiry set for browser caching.

If both conditions apply, the proxy will return the requested resource to the browser.

If any of the two conditions fails to verify, the proxy will fetch a copy from the origin server (where the website is hosted), will deliver the requested resource to the browser while keeping a copy for future requests for the same resource.

Browser cache

#

Browser caching refers to how web browsers keep a copy of assets used by a web page.

This includes:

  • The page itself (HTML).
  • Images, videos, and audio files.
  • CSS and JS files.
  • Fonts.
  • RSS feeds.
  • And also any other static asset.

We can control if the asset can be cached or not, and if does, we can control the duration of the cache.

When the duration of the cache elapses, the browser will look for a fresher version of the asset.

The following is how Apache and Litespeed add browser caching using the htaccess file:

What should be cached? (and what shouldn’t be cached)

#

In a utopic world, every single page on a website should be cached.

Why?

Because you get the best possible speed out of it.

Realistically, not all content can be cached would be for short term or long term.

Only content deemed “static” should be considered for cache.

The following is when you can’t/shouldn’t cache a page:

Dynamic content (when generated by PHP)

Dynamic content is meant to change while the page is generated. In some occasions, conditions apply to show (or hide) specific parcels of content.

Traditional implementation of dynamic content will hard code the output inside the HTML code.

The issue when caching is enabled is the following:

  • The first visitor will generate the cache.
  • All following visitors will get that same version of the previously generated page until the cache is purged.
When is it noticeable?
  • When you use trending posts widgets.
  • When you use conditions to show a banner.
  • When you use geo-targeting.
  • When using forums, social network plugins (like BuddyPress, Pepso, and similar).
Possible fix?

Luckily, there are a couple of workarounds, but it requires that the theme/plugins developers implement them.

One of them is using AJAX.

When a dynamic content is Ajaxified, it will get the right content regardless if the page is cached or not.

Think of it as wholes on your page that are filled after the page loads.

Another one can be using different cache versions of the page depending on a cookie.

We can see that kind of accommodation on geo-targeting with cache plugins able to set different versions of the page depending on a cookie or a query string, like WP Rocket (dynamic cookies documentation).

Without that kind of implementation, you should simply exclude any page fitting that profile (with dynamic content).

The only exception is running highly dynamic content (like forums and social networks). Page caching should be avoided all together on these use cases.

Security nonces

This one is a bit tricky and usually overlooked.

A nonce is a “number used once” to help protect URLs and forms from certain types of misuse, malicious or otherwise.

WordPress – https://codex.wordpress.org/WordPress_Nonces
WooCommerce nonce

Nonces are security tokens used by some plugins to check if a request is valid for some types of actions requiring some level of “security”.

When these nonces are printed on the HTML output of the page, and thanks to the limited “lifetime” for each one of them, caching the page will result in an error when trying to use the feature depending on the nonce.

When is it noticeable?
  • When you are using forms.
  • When you are using ecommerce plugins (like WooCommerce).
  • When you are using calendars with booking features.
Possible fix?

The same rule applies :) For things to work with page caching, they need to be Ajaxified.

Re-thinking the flow is also a way to accommodate.

Instead of implementing the feature that will require a valid nonce to run, you designate specific “action” pages to solely be used for that feature and add buttons to all other pages for that action page.

The best illustration of this is when you use WooCommerce:

  • Product pages can be safely cached.
  • Pages requiring the nonce to run (cart page and checkout page) are uncached and separated from the others.

Application-level (WordPress)

#
You can filter the recommendations by targeted web vital:

HTML, CSS, and JavaScript

#
Stop using jQuery when possible
#
Targeted Web Vitals: Total Blocking Time (TBT)

jQuery is a massive part on so many themes.

Unfortunately, their library can be a performance dragger, especially if it can’t be deferred.

If you can manage to live without jQuery, turning it off totally will give a noticeable boost on the Time to Interactive metric.

The following website provides good alternatives to jQuery functions:

You Might Not Need jQuery

You can use the following snippet to totally remove jQuery from your website:

Let’s take BriskPress as an example.

I use the Oxygen builder as a theme, which uses jQuery on different components, like the menu, the modal, and other features.

In order to disable totally jQuery, I had to sacrifice dropdowns in the menu and add a vanilla JavaScript modal (based on the Glightbox modal), and refactor some jQuery scripts to use pure JS only.

jQuery-free themes/plugins
[wpv-view name=”recommended-assets-per-tag-list” term=”jquery-free”]
Avoid expensive CSS properties and JS functions
#
Targeted Web Vitals: Total Blocking Time (TBT)

Heavy JS calculations will stress the CPU and delay interaction.

Complex CSS layouts needing calculation, filters, and transform directives require CPU resources and time to execute.

Here is an example:

Identifying the problem

Running a performance audit on your favorite browser’s dev tools will help you identify the culprits.

Enable browser’s Performance audit tool

Use Firefox or Google Chrome DevTools Performance panel to find the culprit:

Click on F12.

More tools.

Check the Performance Monitor.

How to find heavy proccesses

Use Firefox or Google Chrome DevTools Performance panel to find the culprit:

Click on F12.

Click on the Performance tab.

Record and analyze the results.

The fix

For CSS

Don’t abuse the following CSS properties:

  • :empty
  • :nth-child
  • :nth-of-type(n)
  • :nth-last-child(n)
  • :not
  • border-radius
  • box-shadow
  • filter
  • position: fixed
  • transform

Same can be said about using Base64 Bitmap Images:

  • Typically 30% larger in size than the actual image (yeah, that’s crazy!).
  • The browser needs to parse it before it appears.

For JavaScript

  • Avoid global variables.
  • Avoid unwanted loops, such as for/while.
  • Avoid using the eval() function.
  • Avoid using the document.write() function.
  • Reduce Activity in Loops.
  • Reduce DOM Access.
  • Use pure JavaScript when possible, like document.getElementById() instead of jQuery() to find IDs.
  • Use XMLHttpRequest when possible (some browsers don’t support it.)
Avoid using @import rule
#
Targeted Web Vitals: Total Blocking Time (TBT)

Each @import target-file is considered as a request. And browsers will need to load and parse it individually.

It may result in a series of render-blocking events.

Another throwback of the @import tag is that it nullifies the effect of combining CSS files. @import within CSS files are still processing as a request, which defies the reason why we combine assets in the first place.

The fix

Add additional CSS files using the <LINK> tag.

This is more of a good practice when you are coding things yourself. 

It is hard to enforce when using 3rd party themes or plugins as the developer usually overlook that practice and @import other CSS files for convenience rather than use the the <link> for efficiency. 

How about CSS added by themes or plugins using @import?

The same rule applies (replacing @import with a proper <LINK>

Swift Performance Pro has an option called “Bypass CSS Import.”

The feature finds @import directives in CSS files and replaces it with the actual CSS code that is supposed to be requested.

This only works for CSS files subject to merging or combining though.

HOW TO PROCESS @IMPORT ON SWIFT PERFORMANCE PRO

Go to Swift Performance > Settings > Optimization > Styles.

Scroll down until you reach the option “Bypass CSS Import”.

Enable it (the button should turn green).

Avoid using sliders above the fold
#
Targeted Web Vitals: Largest Contentful Paint (LCP)

All sliders, regardless if they are lightweight or not, will have a performance cost.

For the slider to render, it will require processing its respective CSS and JS.

The part that costs the most is loading images related to it. As the slider is above the fold, lazy loading won’t help at all.

The fix

Never use sliders above the fold.

Hero section are usually enough to push for important content and information.

If it can’t be avoided, stick with a lightweight, possible pure CSS slider, and limit the number of slides you have.

Here are a feature examples:

  • Pure CSS Slider

Make sure you reserve the height and add the same background as the first slider to limit the CLS effect.

Use more efficient CSS layout techniques
#
Targeted Web Vitals: Cumulative Layout Shift (CLS)

Some CSS properties use extensive hacking and tweaking to get the job done. As a result, the browser will spend more time calculating the layout.

The “float” property is a good example. It requires playing with margins/paddings to control the layout.

The fix

Use less computing-extensive properties.

For the “float” example, switching to “flexbox” to build layouts gives better control without having to extensively code your way to it. More importantly, it helps the browser have less calculating to execute the desired layout.

CSS & JS combination and minification
#
Targeted Web Vitals: Total Blocking Time (TBT)

WordPress, its themes, and its plugins depend massively on static JavaScript and CSS files.

All these components enqueue scripts and styles individually.

If left as it is, this will create a massive amount of requests and sparse “directives” to be handled by the browser.

The fix

Combine JS and CSS to send fewer requests to the server.

Some will argue that it’s not required when using HTTP/2 as a protocol, which is valid to some extent.

HTTP/2 has concurrent assets download thanks to its request multiplexing feature. It’s convenient for browsers because they now can receive multiple requested files at once. There is no waiting to receive scripts.

The problem arises at the server level.

It [the server] will need to handle a batch of multiple connexions at once.

Not much of an issue if you have a couple of concurrent users. But it might cause a considerable CPU stress on busy websites.

Combining files will send fewer requests, and consequently, give less work to the server to handle requests.

Another reason why assets should be combined when possible is network latency on mobile networks.

Latency is the time it takes for data to travel between your device and server. 

Here is the latency for each connection type:

  • 3G ~100ms to 500ms
  • 4G ~50ms to 100ms
  • 5G ~1ms to 10ms

We are up to 500ms delay that will be added to each request. Multiply that by the number for render-blocking scripts, you can end up accumulating seconds.

You need to take “seconds” from the page loading-context, though, where each additional second is likely to influence early exits, users retention, conversion, and ranking.

Better reduce the risks and combine assets as much as possible.

Minification drops the size of the combined assets (or non-combined) assets to the bare minimum to function correctly.

Anything that can reduce the size of assets is welcome.

Most optimizations plugins, like Swift Performance Pro and WP Rocket, will work great.

Important
  • Combining assets might result in conflicts either in functionality (caused by combining JavaScript files) or in design (caused by combining CSS files).
  • Testing is the only way to find non-combination-friendly assets and exclude them from combination.
Load critical CSS first
#
Targeted Web Vitals: First Input Delay (FID)

CSS is a render-blocking resource.

The browser needs to load CSS files one by one and parse them individually.

The First Contentful Paint might be delayed until the browser parses the right CSS to render it.

The fix

Extract and prioritize render-blocking CSS to show content above the fold.

That way, we get the First Contentful Paint at an early stage, even if the full CSS file(s) is not yet loaded.

While it can be done manually by building specific CSS for above the fold content for each page, it’s better and more effective to use a specialty plugin for that.

Swift Performance Pro and WP Rocket can manage to extract and to prioritize critical CSS.

Important
  • Critical CSS is an advanced feature. Most CPCSS extraction engines will rely in one type of browsers and screen size to find elements to style and extract corresponding CSS rules to load in priority. 
  • Misses are frequent. Which leads to FOUCs (Flash of Unstyled Content). 
  • This is where you see content paint with no/shifting style. It usually lasts less than one second, but it’s noticeable to the human eye and can be considered as a user experience issue. 
Make JavaScript non-render blocking
#
Targeted Web Vitals: Total Blocking Time (TBT)

JavaScript is a render-blocking resource. Whenever a browser reaches a JavaScript resource, it needs to parse it first before continuing parsing other elements on the page.

Misplaced JavaScript codes and files might cause a delay in the painting process.

The fix

Placing JavaScript on page footer

The first way to achieve that is to enqueue/place JavaScript in the footer section of the page when possible.

Web browsers will reach it and process it last. 

Deferring JavaScript execution

This can be done by adding the defer attribute to the JavaScript <script> tag.

The defer attribute tells the browser that it should load the script “in background”, then run the script when it loads.

Good to know
  • Just like combination, some scripts may not work properly if deferred. 
  • Checking the browser console will help you identify these scripts and exclude them from deferring. 
Simplify and reduce the size of your HTML page structure (DOM tree size)
#
Targeted Web Vitals: Total Blocking Time (TBT)

HTML document complexity has an impact on the DOM tree size and structure (Document Object Model).

Having a large DOM Tree can impact the loading performance, the runtime performance, and also have an impact on memory usage when combined with scripts targeting general selectors.

Testing tools will flag this as a performance issue too. Eg. “Avoid an excessive DOM size” on Google PageSpeed Insights.

The fix

Use a sampler and leaner HTML structure and avoid the bloats.

Page Builders usually have an excess in code structures and complexity.

Here is the current ranking from the lightest HTML page structure to the heaviest:

OTHER THINGS TO LOOK FOR

Get rid of unnecessary <DIV><SPAN> used as multi-level wrappers when you code directly loops. 

Disable wrapper elements created by plugins when possible (Toolset, for example, has an option to disable wrapping <DIV> on its Views output).

Fine-tune plugins output manually if possible (requires editing some plugins files).

Remove unnecessary Gutenberg CSS
#
Targeted Web Vitals: Total Blocking Time (TBT)

Gutenberg loads a couple of CSS files even if you are not using it.

Dequeuing the files will save you 8kb worth for CSS size and weight.

Not much, but it’s still one feather less on your performance crusade :)

Remove unnecessary CSS and JS files
#
Targeted Web Vitals: Total Blocking Time (TBT)

Most of WordPress themes and plugins are bloated with unnecessary code.

It results in having more requests, large combined files, and browsers needing more time to parse the code. 

This is also now flagged by testing tools.

The fix

Only load the files required to render the page.

Asset CleanUP Pro shines on that specific matter. It gives granular control over assets, so you can load only what’s needed to run the page.

Other types of plugins, like Plugin Organizer, allow disabling entire plugins on specific pages. All assets (JS and CSS) related to these disabled plugins won’t load.

Implementing tree shacking libraries for WordPress

Performance plugins will eventually start implementing tree shacking libraries in order to get rid of unused CSS and JS. 

PurgeCSS is a solid option for CSS (see on Github).

Important
  • Controlling loadable assets comes with a tiny inconvenience.
  • Each page will have its own assets lineup. When combined, you might end up having a unique global CSS file for each page.
  • Assets delivery will happen on each page first load vs. reusing the same combined assets for the whole website. 

Media Assets

#
Better Google fonts management
#
Targeted Web Vitals: Total Blocking Time (TBT)

Using Google fonts, as any non-hosted web font, presents 2 main drawbacks:

  • Overusing fonts will require larger font files to be loaded.
  • Delivering through the default CDN might slowdown loading them.

The fix

Use only fonts and styles that you need. 

For example, if we use the Roboto font for titles only, it’s better to load the Latin, or whatever language you need, and limit the styles pick to Bold 700.

The resulting file will be lighter in weight and faster to download.

Font style non-optimized
Font style optimized

Hosting fonts helps accelerate things a bit. 

Google fonts deliver assets from their own CDN. It can be a speed dragger on some occasions for multiple reasons.

It’s better to deliver everything from the same spot. That way, if you use a CDN, fonts will be also delivered from the same CDN with no speed disparities or delays.

How to host Google Fonts

By using a plugin like Host Google Fonts Locally.

By downloading fonts manually and adding the CSS code to your stylesheet. Google Webfonts Helper will help you extract the right font files and give you the right CSS to add.

Important
  • When using multiple Google fonts, it’s best to group them under one request. 
  • This might not be possible when the theme and multiple plugins each call their own fonts sets.
  • WP Rocket has the ability to group Google fonts and apply the appropriate optimizations. 
Load fonts with font-display: swap
#
Targeted Web Vitals: Cumulative Layout Shift (CLS)

If the  font-display is not explicitly set on @font-face declaration, the browser will use a block value for it. 

 font-display: block; tells the browser to render the text using that particular font to remain invisible until the font is loaded. 

It doesn’t influence performance by itself, but it usually results in FOIT (flash of invisible text), which has an influence on the user experience, and on testing scores.

The fix

FOITs can be avoided by adding font-display: swap; to the font declaration CSS. 

The swap value tells the browser to show the text immediately in a fallback font until the custom font is loaded. 

If the font loading is delayed for whatever reason, we might get a FOUT (flash of unstyled text). 

That can be avoided by doing an early preconnect for fonts on the top of the web page. 

A special case when using Google fonts embedding link. 

The current version of Google fonts allows adding the swap  as a query string on the embed URL. 

Some themes/plugins may still be using the older version of Google fonts URLs. In such case, fonts &display=swap should be added manually to fonts <link>.

WP Rocket adds automatically the missing &display=swap when grouping Google fonts. 

It’s the same feature mentioned before that can be found by going to WP Rocket > File Optimization > Basic Settings > Optimize Google Fonts.

Self-host Google fonts
#
Targeted Web Vitals: Cumulative Layout Shift (CLS)

Most Google fonts implementation is done through there CDN.

You just go to their font generator, grab a mix, and use their CDN link.

For Roboto for example, the link will look like:

<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Roboto:[email protected]&display=swap" rel="stylesheet">

Notice the https://fonts.googleapis.com/css2 part.

This means that the font will be served from Google’s server.

This was the norm. Until something called “cache partitioning” came to play.

Cache partitioning is basically isolating each website’s assets.

Right now, only Safari (the first to implement it) and Google Chrome and its derivatives (since October 2020) are using it.

To better understand what is going, here is a comparison how fonts are loaded with and without cache partitioning:

  • Without cache partitioning, the same font could be used on multiple websites without having to load it each time (improves perceived speed on the client-side).
    This means if you have the Roboto font on your website, and the visitor has already used that particular font from Google’s CDN on another website, then it won’t be loaded again and will be directly served from the browser’s cache.
  • With cache partitioning, each website will have to download its own Google Fonts from the CDN.

The main advantage using Google’s CDN is that there were a good chance that fonts are already available on the browser’s cache and won’t need to be loaded again.

The fix

You can use one of the many plugin that host Google fonts automatically on WordPress.

OMGF | Host Google Fonts Locally is a popular choice for that particular feature.

Optimize hosted fonts
#
Targeted Web Vitals: Cumulative Layout Shift (CLS)

Web fonts ship in general with more characters than you would typically use.

Average use should only include lowercase and uppercase characters, numbers, and punctuation.

But in most cases, fonts will include currencies, math symbols, language-specific letters, punctuation, and accents.

It’s a good thing to have if you are using the extras. But if you don’t, you will just be adding the to the font’s weight without using any of the additional characters.

The fix

The fix is subsetting the font to only include what you need.

Subsetting is creating smaller files with fewer characters from a larger font file.

The impact on performance will depend on how large the un-subedited file is.

A quick way to assess if you cold benefit from subsetting is by running a check on Wakamai Fondue.

But overall, it should still reduce fonts sizes, and will help speed up the initial load of the font.

Add height and width for images
#
Targeted Web Vitals: Cumulative Layout Shift (CLS)

Images without explicit height and width will create a layout shift when the page loads.

You can see the experiment right here. Try to run the test by throttling the network to 3g fast (to make the issue more visible).

The fix

Add the height and width to all images. Especially the ones above the fold.

Themes, and plugins, should normally serve images with an explicit height and width. If you have some images missing these two attributes, reach out to the developers and see if they can add it out of the box.

Guttenberg themes tip

If you are using a pure Guttenberg theme, images height and width are automatically set on the images block.

If you are still missing any of the two on the front end, make sure you check the Image Block Element > Image Settings and verify if the height and width are properly applied.

Guttenberg Image Block Height and Width
Feature available on WP Rocket

If you are using WP Rocket 3.8+, you can use the Add Missing Image Dimensions feature.

Enable “Add missing image dimensions on WP Rocket”

Go to WP Rocket > Media

Enable the checkbox under Image dimensions > Add missing image dimensions.

Clear the cache.

Compress images
#
Targeted Web Vitals: Largest Contentful Paint (LCP)

Images can drastically increase the page size if left without proper compression.

It’s even worse and more penalizing when browsing on mobile.

The fix

Compress images until there is no visible visual defect.

Most image compression plugins, like Imagify or ShortPixel, will offer a “lossy,” “glossy,” and “lossless,” respectively going from the more to the least visual quality loss.

Glossy is the safest pick. Lossy can work in some cases.

Important

Some people think that it’s best to compress an image before uploading it to WordPress.

WordPress will need to re-process the image to create different sizes of these pictures. There is a high chance that the image will be served in a resized format and not as a full-scale image. And that makes pictures lose any prior compression unless you have a compression plugin.

Why? Because those resized images can’t be compressed outside of WordPress.

Technically it can be done. But it will be technically challenging and time-consuming to proceed that way vs a 1-click optimization using the right plugin:

  • Connecting through FTP to download the wp-content/uploads folder, process the images, and send it back is time-consuming.
  • Mounting the wp-content/uploads as a local folder to process it locally is technically and very slow to sync.
  • Using bash scripts and CRONs to periodically process the wp-content/uploads is technical.
Use WebP when possible
#
Targeted Web Vitals: Speed Index (SI)

JPG and PNG don’t have the best possible compression.

The fix

There is a better compression for images that can preserve the visual aspect while keeping the file size lower. It’s the WebP format (backed by Google).

WebP offers a 30% average save compared to JPG or PNG.

It can be used directly on a <img> tag.

Or using a fallback through the <picture> tag.

While it’s possible to implement WebP manually using the appropriate tags, it is best if left for a specialty plugin, like Imagify or ShortPixel.

Important
Use adaptive images
#
Targeted Web Vitals: Speed Index (SI)

Images are usually served with a larger size than their wrapper element. This might result in adding more page size than it should.

The fix

Most image processing plugins, like Imagify and Shortpixel, allow serving responsive images thanks to the srcset attribute. 

Without server the perfect size to fit the wrapper element, this usually have a positive impact on the overall page size.

There is no good self-hosted adaptive/responsive image plugin from within WordPress.

All production-ready solutions will bill you per usage because they highly depend on CDNs.

Here are a couple of options:

  • ShortPixel‘s ShortPixel Adaptive Images plugin (45 CDN locations through StackPath.)
  • Optimole‘s WordPress plugin (180 CDN locations through Cloudfront.)

Optimole has a free tier for 5k visits/month but the CDN is limited to 40 locations only.

Lazyload images
#

Browsers will upload all the media assets regardless if they are above the fold or not.

This slows down the page loading and delays the FCP.

The fix

Implement a lazy-loading JavaScript framework.

While it’s possible to do it manually, it’s best to use a specialty plugin for the task.

Some performance plugins, like Swift Performance Pro and WP Rocket, have lazy loading features. There is one specialty plugin called Flying Images, doing it well too.

Good to know

Google Chrome has its scriptless “Native Lazyloading” process. It only requires adding an additional loading="lazy" attribute on images. The <IMG> tag will look something similar to:

WordPress has implemented native lazy load for images, which can seem to be good on paper.

The hidden detail is that browsers native lazy loading has a 4000px threshold. Which is pretty far from above the fold, and therefore, nullifies any lazy loading benefits.

It’s best to implement a script-based Lazyloading system. This allows us to have a lower threshold and of course control it at will.

WP Rocket for example has a 300px threshold and has hooks to control it if needed.

This can be done by using the following filter: 

100 here reflecting the 100px as the new threshold. 

It also has a filter to allow the native lazy loading to kick in first, and then use the script based lazy loading when needed. This can be done by using the following filter: 

When using the Native Lazyloading, there is a potential enhancement on the Time to Interactive as this part will be directly managed by the browser and not using a script.

Lazyload Youtube, Vimeo, Soundcloud
#
Targeted Web Vitals: Total Blocking Time (TBT)

Videos hosted on 3rd party platforms, like Youtube and Vimeo or SoundCloud, will load the player and start preloading the video/audio file right away.

This happens even if:

  • The video is now on the viewport.
  • Visitors don’t engage with video.

The fix

Lazyload is the best fix for 3rd party streaming players. 

Just like lazy loading for images, the video or audio player only loads when it’s on the screen’s viewport. So, no script related to the player is loaded IF the actual player doesn’t show above the fold.

Performance plugins, like WP Rocket, can handle that natively.

For a maximum performance boost, it’s best to only load the player if the visitor wants to use it.

The idea is to replace the video with a preview image. The actual player only loads after the visits click on the play button. 

The Velocity plugin handles that perfectly. It has a manual process to load the preview image, but the performance impact is great. 

You’ve seen that in action implemented in all videos used in this course :)

Themes & Plugins

#
Use hosting or server-side backups
#

Backups are very important as part of any WordPress security strategy.

The only issue is that when the backup is performed using a plugin, there will be a consequent performance cost at the time the backup is running.

The following are some plugins fitting that profile:

The fix

Use the hosting service backup system if available.

VPS hosting providers like Digital Ocean also provide backup options for servers.

A healthier option is to use Linux command line to perform periodic backups using Crons.

A full WordPress backup can be done with the following two basic lines:

A more elaborate backup shell script can look like this:

Another variant using WP-CLI:

#

Broken link checkers depend on Cron jobs and have an extensive process to find and report broken links.

The following plugins fit that profile:

The fix

Use external services like Google Search Console to do the exact same thing with no overhead of the server.

SaaS services like Dead Link Checker or scrapping tools like Screaming Frog can be considered as well.

Use image compress tools that offload compression to their servers
#

So image compression plugins rely on PHP ImageMagick or GD libraries.

Running image optimization through that kind of plugins has a considerable server overhead.

The fix

Avoid any image compress or optimization plugin that relies on PHP libraries.

Here is a list of known plugins fitting that profile:

  • EWWW Image Optimizer.
  • Imsanity.
  • Smush – Lazy Load Images, Optimize & Compress Images.

Use instead plugins with compression capabilities on their SaaS services, like:

You can also opt to manually compress image using services like Google’s Squoosh App.

Exploring server-side image optimization libraries like Thumbnailator could be an option too.

Avoid using security plugins when it’s an option
#
Targeted Web Vitals: Total Blocking Time (TBT)

Security plugins do their job by monitoring requests. Most of their actions are done through PHP processes, which has a high impact on performance.

The list includes:

  • Wordfence.
  • Sucuri Security.
  • iThemes Security.
  • All in One WP Security and Firewall.

The fix

Service-side security provides the same level of protection (if not better) than security plugins.

All lock-downs, scans, and patching are more efficient and much faster if done on the server-side as server directives. 

Most hosting services deploy security protocols and routines at the server level. 

And there are plenty of options to use if you manage your VPS or dedicated server yourself.

Scanners:

Firewalls:

Extract specific functions from plugins when possible
#

Plugins come with a bunch of features and functions. More than often, the code base is meant to do way more than the specific feature you need.

The fix

On some occasions, it’s possible to extract specific functions and use them to do the job instead of using the whole plugin.

Spotting, extracting, and using the function requires coding skills.

Find and fix slow queries
#

Poorly coded themes and plugins usually take more time to extract data from MySQL.

The fix

A quick fix is to use Object Cache to help temporarily store (cache) queries.

A popular solution is the Redis Object cache plugin

Please note that in order to use Redis Object cache, your hosting service must have Redis enabled on your server.

It’s best though to find out what is causing these long queries (is it your theme? is it one of the plugins?) and either fix it to replace it with a better and performance-focused option.

A slow query refers to queries that spend more than the time stated on long_query_time (a parameter you find on my.cnf file). By default, MySQL tags any query needing more than 10 seconds to generate as a slow query, which usually delays picking themes or plugins with slow queries.

It’s better to set it to a lower value to 1 to 2 seconds for lightweight websites. A bit more for high content websites and stores.

How to enable logging slow queries in MySql

Log in to your server using SSH.

Locate my.cnf file and open it using your favorite command-line file editor (like VIM or Nano).

Find the long_query_time line.

Modify the surrounding line to reflect the following:

Save.

Reload and restart the MySQL service.

In this example, we’ve set the slow query to log if it’s longer than 2 seconds.

You can find all entries by going to /var/log/mysql-slow.log.

You can either monitor it live by using something like tail -f /var/log/mysql-slow.log or by using mysqldumpslow /var/log/mysql-slow.log to read the file.

Things can be much easier if you use some server performance tools that can monitor slow queries. Like Retrace, or Datadog, or New Relic (pricey).

If you use any performance tool for find slow queries, make sure to turn it off after you finish profiling the source of the issue :) 

Pick quality plugins and themes
#

Going for cheap assets might result in a lot of poorly coded function and conflicts, which ultimately results in:

  • More processing time at the server’s end.
  • Longer interaction on the front-end.

The fix

You get what you pay for when purchasing WordPress assets.

So, pick themes and plugins based on their code quality and not their pricing

Reviews and online-reputation come handy to find the right developer for the kind of themes/plugins you need. You just need to spend some time researching and not just decide based on the item description and a couple of reviews.

Picking the right theme
#

We have to kind of scenarios:

  • Commercial multipurpose themes are usually bloated with features, assets that are overkill for what you are trying to do. 
  • Oversimplified themes, with fewer features than what you need, will force you to add more plugins to achieve the desired functionality. 

Both have good chances to influence the overall performance of the site.

The fix

It’s a good practice to list all the features you need for your site. Preferably with some overcasting to potential needs in the near future or mid-term. 

This is will help you set target features to look for when picking a theme. 

Try to find themes with most of the features you require to lower the need for adding additional plugins.

Can’t find anything that will get you closer to what you need?

Pick a low footprint theme and try to limit plugins usage. 

Another way to tackle that is to use a helper plugin, like Toolset, to have more flexibility personalizing your website without having to add tons of plugins.

Using Toolset, you can build:

  • Directories.
  • Testimonial forms.
  • Content submission systems.

Check out their showcase directory to see what Toolset can help you build.

Get plugins from the same provider when possible
#

Plugins use the same WordPress API but in a different way. They also introduce their hooks and functions.

When using plugins from different providers:

  • Conflicts chances increase.
  • Overcomplicate possible communication between different plugins.

All can contribute to more processing time at the server-side.

The fix

Pick plugins from the same provider when possible.

Plugin authors usually build complementary features or interconnect their plugins to serve as an ecosystem rather than a standalone feature.

Same developer = Same logic = Same codebase. And most of all, the plugins’ set is built to communicate and interact with each other from the ground up.

You get a leaner code execution as a result.

Here is an example of plugins suites fitting that profile:

If you need one plugin from a set provider, you are more likely to need the rest of them too :)

Use scriptless sharing buttons
#
Targeted Web Vitals: Total Blocking Time (TBT)

Social media plugins may use JavaScript to run part of the sharing mechanics and to display shares counts.

It sure can look fancy, but it comes at a performance cost.

The fix

Using the Scriptless Social Sharing plugin can be a great compromise to keep the sharing feature without hurting speed and user experience. 

This plugin uses the most basic method for social sharing to happen. It’s stripped from:

  • JavaScript code.
  • Calling extra files.
  • Or using server Ajax calls.

Alternatively, you can use the following snippet on your functions.php file to build a low footprint social sharing shortcode.

The following is the output:

[social]

Here is the snippet to use on the functions.php page:

Important
  • Both options don’t support shares count.

Others (WordPress)

#
Avoid page builders or use low-footprint ones
#

Page builders may make designing website much easier, but they come with a noticeable server overhead as well as a lot of bloat.

Ideally, you should stick with the Gutenberg builder which is evolving steadily to be more of a website builder than only a page layouting tool.

Using custom fields like Advanced Custom Fields or Toolset with a custom template are also a great alternative to page builders.

If a page builder is a necessity, opt of something with a low footprint and built for performance in mind, like Oxygen.

Avoid at all costs the following page builders:

  • Divi (they promised that they will address performance issues in 2021)
  • Elementor (getting better, but still bloated)
  • WPBakery (unfortunately, this one is by far the worst builder for performance out there)
Switch from WP-Cron to server Cron
#

WP-Cron has limits and performance issues.

First of all, WP-Cron is just a way WordPress to mimic what the system cron does (the server-side cron).

It’s reliance on PHP makes it a performance dragger for many considerations.

WP-Cron runs on each page load.

On low traffic websites, schedules could be missed if there is no visits for a while.

On high traffic websites, WP-Cron will fire continuously even if it’s not really needed. That is an extra process that the server will need to handle.

Just like any PHP code, WP-Cron will need to wait for available PHP workers to run. That means, even if a page load fires the Cron, it might have to sit in a queue waiting for its turn to run, and delay all background processes depending on it.

It is best to use a server-side Cron to cut short performance issues related to the native WP-Cron.

To do that, the first thing required is to disable WP-Cron by adding the following constant on your wp-config.php file.

define('DISABLE_WP_CRON', true);

The second part is to set up the Cron on the server-side to fire either using WP-CLI, PHP, CURL, or WGET (by order of preference).

Access the server’s terminal using SSH.

Run the following command:

crontab -e

And add the following line at the bottom of the file depending (adjust it to fix your server’s domain or location path):

*/10 * * * * wget -q -O - https://domain.ext/wp-cron.php?doing_wp_cron >/dev/null 2>&1
*/10 * * * * curl --silent "https://domain.ext/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
*/10 * * * * cd /path/to/wordpress/root; php -q wp-cron.php
*/10 * * * * cd /path/to/wordpress/root; wp cron event run --due-now

The process will be different depending on your hosting service. Some hosting services have a section to manage Crons from their panel, like Cpanel.

Server-side

#

Server Hardware

#
Avoid shared hosting services
#

Shared hosting is the most prominent form of WordPress hosting.

The pricing is very attractive, but the performance is deplorable, especially on traffic spikes.

The fix

Dig deep to find a decent shared hosting. We unfortunately don’t have any recommendations for that department. And we can’t recommend anything that we don’t believe in :)

The only advice we can provide though is to NEVER go for anything other than a monthly subscription for shared hosting. Performance tends to degrade with time, and getting a longterm commitment paid upfront is just not the greatest idea, even if the offer looks like a steal. Another practice is to lure you on an unlimited plan that turns out to be limited, and the only way to keep using the service is either to get the upper plan or lower your resources usage.

What we recommend

Go for a mid-range (like Flywheel) or a high-end (like Kinsta) WordPress hosting service. Serious managed web hosting bill per visit and use a fairer server share instead of overpopulating servers. They also come with better stacks and security. 

Use unmanaged hosting with a panel. Running your own server is no longer as challenging as it used to be thanks to server panels like RunCloud paired with VPS services like Vultr High-Frequency servers

Important
  • It is preferable to have some notions of sysadmin to go for your own servers, even if the server panel does most of the heavy lifting.
Pick the right type of servers for your needs
#

We always want to go for the cheapest possible option.

That mindset leads ultimately to underperforming servers compared to your needs.

The fix

The server’s horsepower is what’s behind executing requests.

It’s easy maths:

The better the hardware you have (CPU, RAM, hard drive) = the faster the server can process tasks and return responses = the better the performance will be.

There are plenty of good options depending on your budget and use case:

  • Budget KVM VPS providers, like Digital Ocean, Vultr, or Ramnode, can give you decent specs for the price.
  • Baremetal or dedicated resources will lock down the resources you pay for to be strictly used by your web properties.
  • High-end cloud hosting, like Google Cloud or Amazon Web Services, can provide a scalable environment to fit your needs if you have enough budget to go that road.

VPS, and hosting providers in general, rarely include what type of hardware they use, and don’t give thorough information about the specs. Luckily, there is a VPS Benchmark Script that can extract on your server and run on your terminal to get an in-depth specs view.

You should, of course, have a basic understanding of what the specs mean and which ones are best.

Too lazy for that? or don’t have enough computer knowledge to read the specs?

VPS Benchmarks are a great resource to compare VPS providers. They periodically test and grade VPS from known providers.

Important
  • Unless stated otherwise, VPS services have shared CPUs (sometimes referred to as vCPU). It’s subject to a fair use policy, which doesn’t allow the user to use more than 20% – 40% CPU power continuously.
  • Shared RAM (sometimes referred to as burst RAM) can be very deceptive. You think you have a set amount of RAM to run your web site, but in the end, you only can access half or 1/3 of it.
  • Hard drives must be either SSDs or NVMes. Both are fast enough and drastically reduce the read/write processes.

Server Stack

#
Pick the right PHP process manager controls for the task (Nginx using PHP-FPM only)
#

PHP process manager has 3 ways to control the number of child processes:

  • Static: the child processes are always available to hand requests.
  • Dynamic: there will be a minimum of available child processes at the start, and scale up/down when needed.
  • Ondemand: the child processes are fired upon request and terminated after an idle time.

For more, check PHP: Configuration manual

VPS panels default setup usually comes with ‘dynamic’ set out of the box, while managed hosting services might impose using ‘ondemand’.

Using the wrong controller might cause the performance to degrade.

The fix

Pick the right way to control the number of child processes depending on your needs.

What is the performance gain?

From my testing, it’s a 50ms up to 400ms gain per request depending on the load (the difference accentuates as the load increases).

Note: the configurations are for reference. You will need to adapt them to your environment.

When to use ‘static’?

Static is the setting that will give the best performance. Child processes are ready to take requests immediately.

pm = static
pm.max_children = 15

The drawback is that these child processes will hold the server’s RAM, even if there are no requests to process (no traffic).

Setting the PM to static will benefit more high traffic websites, e-commerce, course/membership websites that require logging in, community websites running BuddyPress, BBPress, PeepSo and similar.

Visitors flow doesn’t stop, and therefore, it’s only logical to always the child processes fired and waiting for requests to process.

Static should be considered in any set up that can afford to lock memory for PHP to use.

When to use ‘ondemand’?

Ondemand is the most used process management control strategy.

Child processes are only created when needed and terminated. This will preserve the server’s resources.

pm = ondemand
pm.max_children = 15

It’s best to be used with mostly static content that can be cached.

When to use ‘dynamic’?

Dynamic is the middle ground between the two other options. You have some child processes ready to use immediately (like when using static), with the possibility to scale up and down when needed (like when using ondemand).

pm = dynamic
pm.max_children = 15
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 10

The main drawback is that this approach might be difficult to fine tune.

You might get periodically have 50x error with the following error showing on your logs:

WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 2 idle, and 23 total children

It can be tested on websites with low/fluctuating traffic.

Serve the backend and the frontend from different pools when possible

Traffic going to the backend vs. frontend is usually uneven.

If you want to spare most of the resources to serve the frontend (ex. if you have large e-commerce store), you can create different pools to server the backend with lower priority and the frontend with a higher priority.

This can be done on the www.conf file (or the equivalent on your environment) as follow:

[wpfrontend]
listen = /var/run/php-fpm-frontend.sock
user = XXX
group = XXX
listen.owner = XXX
listen.group = XXX
pm = static
pm.max_children = 10

[wpbackend]
listen = /var/run/php-fpm-frontend.sock
user = XXX
group = XXX
listen.owner = XXX
listen.group = XXX
pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s

And reference each pool to handle specific URL patterns on your server block as follow:

set $fpm_socket "unix:/var/run/php-fpm-wpfrontend.sock";

if ($uri ~* "^/wp-admin/") {
  set $fpm_socket "unix:/var/run/php-fpm-wpbackend.sock";
}

Modern server stacks are a must-have
#

Older web server technology performs noticeably less than it’s updated version.

PHP 7.x has doubled the performance of PHP 5.6 since it’s initial release in late 2015. And yet, half of the web still uses PHP 5.x (according to W3Techs.)

The same applies to Apache. Nginx and LiteSpeed handle way more requests than Apache while using fewer server resources, and yet, again, half of the web still uses Apache as their web server (according to Datanyze.)

The fix

Use a modern web server stack.

For the server

Make sure you use either LiteSpeed, Nginx, or a hybrid Nginx/Apache setup. Just avoid using Apache standalone at all costs. 

LiteSpeed commercial web server has a performance boost on serving static assets, but it’s only noticeable when dealing with large traffic. It has also the edge with its own caching plugin, LiteSpeed Cache, which has a lot of premium features provided for free.

Hybrid setups using Nginx with Apache is a good alternative when LiteSpeed is not available. That hybrid stack is executed nicely by RunCloud :)

It allows plugins like WP Rocket to have a better performance by using htaccess on Nginx as part of its tweaks.

For the database server

MariaDB 10.x and MySQL 8.x are equally good. Any of the two will help you get the best performance possible in this department.

PHP version

7.x is what you are looking for. The most current version, the better (we are currently at 7.4.x).

Important

LiteSpeed has 2 distinct products:

  • OpenLiteSpeed, the free community web server.
  • LiteSpeed Enterprise, a subscription-based web server.

LiteSpeed Enterprise has earlier technology implementation and some advanced features compared to OpenLiteSpeed.

Off-Server

#

DNS

#
Prefetch DNS
#

Like we described in the DNS Resolve section, DNS Lookup can take up to 8 steps in order to resolve the domain to an IP address to process requests.

Factor that to the number of 3rd party domains you might need to embed files from analytics, trackers, pixels, CRM scripts. That might turn up to take a considerable time for the first request of each domain.

The fix

Prefetching DNS orders the browser to initiate the DNS Lookup for domains that the page will need at some point.

The browser will run the DNS Lookup on the background and cache the result. This will speed up considerably future connexions to the prefetched domains.

Prefetching is done by adding a <LINK> tag with rel="dns-prefetch" in the <HEAD></HEAD>.

Something like:

It can either be done manually or using optimization plugins that can handle it with minimum intervention.

Swift Performance Pro and WP Rocket both have domain prefetching using a single option to check. The whole process is done automatically, including looking for 3rd party domains and adding the right <LINK> to the page <HEAD> section.

Use a fast DNS service
#

Most domain registrars and hosting services enforce using their DNS service. Performance is usually pretty low compared to specialized services.

The fix

Dedicated DNS services can give better domain management and of course, much faster DNS response.

DNSPerf ranks DNS services overall speed worldwide and by continent.

Here is the list of the 15 best performing DNS services worldwide:

Top 15 DNS providers
Top 15 DNS providers

Cloudflare is a consistent and solid choice for the following reasons:

  • It’s fast.
  • Has a great free firewall and protection layers (free and paid).
  • Built-in CDN.
  • Edge SSL. 

Their free plan is more than enough in most cases.

SSL

#
Pick the right SSL key size for the use case
#

Lengthy SSL keys require more CPU power and time to work. 

The fix

Enabling SSL for a website has an overhead on both the server-side and the browser-side. 

That overhead depends on the key length used by the SSL.  

[ninja_tables id=”2058″]

Smaller keys means:

  • Smaller certificate size 
  • Less data to pass around
  • Quicker to download
  • Faster TLS handshake
Use the ECDSA algorithm if possible
#

Cryptography algorithms have different performance. The most spread one, RSA, is not the fastest out there.

The fix

ECDSA is able to provide the same cryptographic strength as an RSA-based system with much smaller key sizes. 

It has an even smaller footprint as the encryption scales. 

[ninja_tables id=”2068″]

Free certification authorities offering ECDSA:

  • Cloudflare already uses ECDSA for its edge flexible SSL. Which is part of the speed boost we usually witness when enabling it. 
  • Let’s Encrypt, the goto free SSL provider, now generates ECDSA root and intermediates which can be used to sign end-entity certificates.

Paid certification authorities offering ECDSA: 

  • Comodo
  • DigiCert
  • Entrust
  • GeoTrust
  • GlobalSign
  • Thawte roots
  • Trend Micro
  • VeriSign

Content Delivery Networks (CDN)

#
Use a CDN to deliver static assets
#
Targeted Web Vitals: Speed Index (SI)

When serving a global audience, the latency to deliver assets (JS, CSS, images) increases as the distance between the visitor and your hosting server increases. 

The fix

Use a CDN to help deliver assets from closer servers for your global audience. 

Cloudflare free plan can help a lot. Even though it’s not a real CDN. But thanks to its integration with performance plugins, like WP Rocket, it’s a cheap and convenient way to benefit from its large network for free. 

Picking a CDN provider is a tricky task, as performance may vary from region to region. 

The right way to find a potential CDN provider, if Cloudflare is not enough, is to check CDNPerf and see which CDN has an overall good performance in most of your target regions. 

Push CDNs usually have easy integration with WordPress.

Here is a list of the most prominent CDNs out there: 

SaaS alternatives to heavy WordPress features

#

Why turn to SaaS while you can run the feature on WordPress?

#

WordPress is very flexible to run a plethora of features. But not all of them can efficiently be run as part of WordPress. 

You should strongly consider to run a feature on a SaaS platform when performance, security, stability, and scalability start to worsen when the feature you are after is enabled.

Here have a curated list of better alternatives to some performance-worsening features when run on WordPress.

Ecommerce

#

Running e-commerce on WordPress is quite popular. It’s fine when you have a couple of products with a couple of visitors buying from time to time. 

Things get more complicated when you have thousands of products and hundreds of users trying to buy from your store at the same time.

Sooner or later, the only option to maintain the store run smoothly is to scale the server as you go. 

A busy e-commerce store can easily hit $200/m hosting budget.

The best thing about turning to SaaS for ecommerce is that all the action is done outside of WordPress’ ecosystem. A decent server and a good caching system will be enough to run the main website, while the e-commerce part will run for the e-commerce SaaS servers.

Another perk for turning to SaaS is that the store lives on its own. It can be used pretty much everywhere and not just limited to WordPress.

Ecwid

Ecwid is a SaaS e-commerce store with a monthly subscription.

Pricing
  • They have a free tier for up to 10 products.
  • $15/m for up to 100 products.
  • $/m for up to 2500 products.
  • $/m for unlimited products.
  • They charge an additional gateway transaction fee ranging from 2.9% to 4.5%.
Advantages
  • It can be run anywhere, including WordPress.
  • You are not tied to a specific website to run the store.
  • The top tier plan can hold unlimited products for $82/m.
    The same will cost thousands of dollars in monthly hosting for WordPress.
  • Has a built-in integration with Facebook, Instagram, and Google shopping.
    The same integration exists on multiple WordPress plugins. But it's prone to errors and can be a pain to set up.
  • An extensive list of payment gateways.

Disadvantages

  • Doesn't have an extensive array of features like WooCommerce for example.

SnipCart

SnipCart is a cloud e-commerce platform with an interesting array of features.

It's ideal to sell individual products rather than run a conventional ecommerce store.

Pricing
  • 2% transaction fee.
  • If sales are less than 5k for a month, the transaction fee is replaced by a flat $10 for that particular month.
  • They charge an additional gateway transaction fee ranging from 2.9% to 4.5%.
Advantages
  • It can be run anywhere, including WordPress.
  • Supports recurring charges and subscriptions.
  • Multi-currency.
  • Can sell digital goods.
Disadvantages
  • Not so many payment gateways (includes Paypal and Stripe though).

Zoho Commerce

Zoho Commerce is a cloud e-commerce platform not very mediatized, but it still has affordable pricing.

Pricing
  • $20/m for up to 5k products.
  • $60/m for up to 20k products.
  • In addition to the monthly charge, there is a 1% to 1.5% transaction fee.
Advantages
  • Integrates well with the Zoho CRM and ecosystem.
  • Multi-currency.
  • Abandoned cart.
  • Fraud analytics.
  • Live shipping rates.
  • Conditional pricing for customers.
Disadvantages
  • Doesn't run on WordPress
  • Not so many payment gateways (includes Paypal and Stripe though).

Funnels

#

There are a couple of highly mediatize funnel plugins on WordPress.

Unfortunately, funnels are just not something that can be performance proficient when used as a plugin.

The main reason why is that checkout, and usual funnel steps pages too, can’t be cached.

You are left with running the funnel with raw server resources, which can quickly be exhausted if facing a visits spike, or customers trying to checkout at the same time (usually happens on campaigns).

ThriveCart

ThriveCart is a features-rich funnel system that includes affiliates and JVs management.

Pricing
  • $495 for the standard version.
  • $690 for the pro version.
Advantages
  • Funnel system with upsells and downsells.
  • Affiliate Center.
  • JV Contracts.
  • Subscription Saver Functionality (Dunning).
  • Automatic Sales Tax Calculation.
  • Custom domain name functionality.
  • Direct integration with gateways.
  • An extensive list of integrations with membership, CRMs, emailing platforms.
Disadvantages
  • Their embed option that can be used on page on WordPress can be buggy at times. It's best to totally externalize the checkout process.

Social networks, forums, groups

#

Anything that requires constant user connexion has a huge influence on performance.

Thanks to the highly dynamic aspect of that kind of features, once the user logs in, chances are very slim that you can deliver a cache version of what they visit.

Not to mention the scalability ordeal as the userbase grows.

Example of plugins fittings that profile:

  • BuddyPress
  • BuddyBoss theme/platform
  • PeepSo

Luckily, there are a couple of SaaS options that can be directly embed on WordPress websites.

And even if the solution is fully accessible outside the website’s premise, it is far better than fighting teeth and nails to get a WordPress highly dynamic users’ driven website to run with no performance issues and without ruining the owner.

Disqus

Disqus is remote commenting system that can be used to offload WordPress comments.

Pricing
  • Basic plan is free with forced ads.
  • Plus plan costs $9/m for 3 websites and up to 50k cumulated page views and disabling ads.
  • Pro plan costs $89/m for 20 websites and up to 150k cumulated page views and disabling ads and other features.
  • Business plan with a custom price for unlimited websites and disabling ads and other features including SSO.
Advantages
  • Comments will have no server overhead.
  • Page cache-friendly.
Disadvantages
  • Users have to create a Disqus account.
  • Design can't be customized.
  • Users need to explicitly unauthorize their data/content selling to 3rd parties.

Hyvor Talk

Hyvor Talk is remote commenting system that can be used to offload WordPress comments.

Pricing
  • Free 14 days trial, but no free plan.
  • Premium plan costs $5/m for unlimited websites, up to 100k pageviews (scalable if needed).
  • Business plan costs $35/m for unlimited websites, up to 500k pageviews (scalable if needed), SSO, and brand removal.
Advantages
  • Page cache-friend.
  • Unlimited websites and moderators.
  • SSO at an affordable price.
  • No data selling.
  • Webhooks.
  • API.

Peerboard

Peerboard is a community engine that can be embedded on any website.

Pricing
  • Have a free tier for public communities.
  • $99/m for up to 500 monthly active users.
Advantages
  • Has an API linked to Zapier.
Disadvantages
  • Very basic community system.

Zoho Connect (External Network)

Zoho Connect is SaaS community engine.

It was initially designed to be an Intranet for companies. Luckily, Zoho though to repurpose it as an fully fledged social network that can be used for any use case.

Pricing
  • $20/m for up to 5k products.
  • $60/m for up to 20k products.
  • In addition to the monthly charge, there is a 1% to 1.5% transaction fee.
Advantages
  • Unlimited users for $100/m.
  • Features social network: forums, boards, groups, events, chat, files sharing, 3rd party integration.
  • Supports custom CSS (handy to match the look and feel of the original website).
Disadvantage
  • It can't be embed as part of WordPress.

Optimizations to speed up WordPress backend-end

#

Application-level (WordPress)

#

Plugins

#
Disable core, themes, plugins updates check
#

WordPress checks for updates checking have their toll on back-end performance.

The fix

These checks can be temporarily disabled using plugins like Disable All WordPress Updates.

Important
  • Make sure to disable the plugin from time to time to check for updates.

Disable BrowseHappy
#

WordPress checks if you are using the latest version of your favorite browser each time you login to the dashboard.

If you don’t have the latest version, it will show notifications like:

  • You are using an insecure browser
  • Your browser is out of date

The check is done using the wp_check_browser_version() function which triggers and processes an API call to http://api.wordpress.org/core/browse-happy/1.1/.

Depending on your server, this will eat round 0.5s to 1s from the first login to your admin section.

Not a biggie, but it can be prevented :)

The fix

The following snippet (to be added to functions.php) will kill the API call and shorten the function’s execution:

Make sure to clear the transient once the snippet in added.

And of course, make sure you always keep your browser up to date :)

Other

#

Server-side

#

Object Cache

#

Queries are requests made to the database to find information to compile and process.

When you browse a product category page, WordPress will send a query to the database to find all products, then filter them, then send back the results.

Object Cache sits in the middle. It monitors queries in way to store the ones repeating often. Once a query’s result is stored, it will be directly returned instead of having to generate a new result.

One of the most popular implementation of Object Cache in WordPress is done through Redis and the Redis Object Cache plugin.

#

Themes

#

Getting the right theme, optimized out of the box, and built to score well on Google PageSpeed is a massive step ahead to get the best possible speed for your website.

Miss the mark, and you might fight hard to “undo” the bloat shipped by some themes, more focusing on being a features-rich, do-it-all, rather than offering a decent speed and performance for their users.

The following is our recommended themes:

[wpv-view name=”recommended-assets-per-category” category=”Themes”]

Page builders

#

Page builders are a convenient way to build pages in a visual way.

Thanks to their pre-made elements and design blocks, page builder cut the coding par in designing websites.

Not all page builders are equals in term of features and performance.

Getting the right page builder is a step ahead faster websites and improved scores.

The following is our recommended page builders:

[wpv-view name=”recommended-assets-per-category” category=”Page builders”]

Performance Plugins

#

Performance plugins help apply performance tweaks that your theme and plugins developers didn’t include to their products out of the box.

There is no perfect performance plugin to do every single performance tweak possible. Instead, we are likely to find specialty plugins specializing on specific kinds of optimization.

As a rule of thumb, you should never have (or enable) the same feature on different performance plugin.

The following is our recommended performance plugins:

[wpv-view name=”recommended-assets-per-category” category=”Performance Plugins”]

CDN

#

Secret performance methods

#

Controllable Cloudflare full-page cache

#

We know by now that serving pages from cache is the best you can get in term of speed. Without considering optimizations within the page itself.

And we have seen that the next level for that is to serve the cache page from a CDN. Which requires a CDN service with edge rules to allow adding conditions to avoid caching the WordPress backend and pages that shouldn’t be cached (checkout pages for example).

Cloudflare is a popular service with a couple of ways to deploy full page cache with a couple of ways to bypass caching at their level if needed.

The issue is to make it support exclusions, you either need to buy more Page Rules, or code a Worker and eventually pay for it if you exceed the free monthly tier.

How about people who can’t afford that? But still want the best they can have?

Well, there is a “trick” to achieve that ;)

Cloudflare free tier comes with 3 Page Rules that you can use with no limits (except that they don’t support cookies).

We can set the Page rules in a way to cache only the front end, and we can use that to add pages that will be bypassed on the front end as well ;)

Let’s deploy the rules, and I will explain the logic.

Set the 3 Cloudflare Page Rules as follow

Please cache everything in my domain *brisk.press/*

But exclude anything starting with wp-, which translate to *brisk.press/wp-*

Except for anything under wp-content, which translates to *brisk.press/wp-content/*

The first step tells Cloudflare to cache everything under the domain.

It’s self explanatory. So, no further explications are required for this one, right? :)

The second rule tells Cloudflare to not cache anything that starts with wp-.

You will see in some tutorials that you should exclude wp-admin instead in order for the backend to be usable.

Excluding wp- will do that as well. And I will explain why we need it that way.

The second rule will bypass cache on static assets delivered from the wp-content folder (themes and plugins JS and CSS files).

That’s the purpose of the 3rd rule. To allow static assets to be cached.

So, back to the why we need to exclude wp- from caching :)

The reason is: so we can use wp- as a prefix to bypass Cloudflare’s full page cache on the front end as well.

How?

Well, by simply added wp- at the start of slugs for pages you want to bypass!

This is what I use to make sure supporter’s pages are not cached!

Delay painting by using content-visibility set to auto (Chrome-based browsers only)

#

Chromium introduced a new property called content-visibility starting from version 85.

It’s part of the CSS Containment effort to give more control and optimization prospects of off-screen contents.

when content-visibility is set to auto, it instructs the browser to skip the element’s layout and painting process entirely (likely putting it in pause) when it’s not needed (off-screen, out of the viewport).

The bad news is that using the directive alone has it’s flows.

Without going into details, using the property alone has it’s downsizes.

For starters, this property can only be used on Chrome-based browsers.

content-visibility browsers' support

Firefox has market it as worth prototyping with the last interaction dates from August 2020. So, it might take a while to see it happen.

No sign or possible discussions in the Safari tribe about it.

Whatever benefits using content-visibility will solely target your Chrome audience.

The most annoying one, that might have consequences on the user experience, is that it’s similar to setting the height to all elements using it to zero. As a side effect, it will trigger loading them all right away.

The fix is to use content-visible: auto; with the properly contain-intrinsic-size: 1px 5000px; to help the browser estimate the size.

But even with that, you might experience some scrolling bar jumps.

The following video will give you more details about it:

The full code looks like this:

You just apply the chosen CSS selector, in the example, the .delay_content class, et voila! You will be delaying rendering the content of your choosing.

To sum it up, it’s basically a hack tricking the browser, with possible minor hiccups.

So why risk it?

Well, because it give the main thread a breather to process more critical rendering.

You can consider using it if the main thread is giving you a hard time to tweak. This will usually happen if you have complex layouts and a lot of content to process (long sales pages, news websites, web shops with extensive homepages and archive pages).

References:

Final word

#

It’s important to start the optimization game at an early stage by picking the right theme, and plugins set, and avoid anything complex unless it’s necessary.

Beyond that, optimizing speed will need more hacking to hopefully improve some of the bottlenecks tackled on this guide.

Working on performance can be very obsessive :) Make sure you find an equilibrium between your efforts and the performance gain.

If you have to spend weeks to figure out how to cut 100ms from your loading speed, it is not worth the hassle :)