Themes can prove to be real blockers in PageSpeed.

We have compared top WordPress themes in terms of PageSpeed and PageLoad – the results can be found here.
The three most popular themes compete against our SV100 WordPress theme in four different scenarios.
Here you can see how the chosen theme alone can have on the pageload – one of the many criteria for the Google ranking.
These WordPress themes have been tested
Avada
Avada is the most popular paid theme on ThemeForest.
OceanWP
is the most popular independent theme in the WP theme repository.
Twenty Twenty
is the standard theme and is delivered together with WP.
SV100
our self-developed theme is available free of charge.
A theme already exceeds the limit
Pagesize
The load time of your website depends heavily on the amount of data that is being transferred. Your visitors need more bandwidth or more patience to view your website. A theme should use resources as sparingly as possible, so that you have more freedom in your content.
Google recommends that a website should not have more than 1,600 kilobytes of PageSize.
Avada requires – without optimization – but already more than 1,700 kilobytes – without content. Therefore, it is better to choose a theme that is more economical with resources.
Below you can see the tested themes – the bigger the PageSize, the worse:
What’s left?
Space for your content
If you follow Google’s recommended PageSize budget – how much space do the WordPress themes give you? We compare here in the optimized scenario, i.e. with activated NGINX + WP-Rocket.
“Your page view is very important to us, please wait…”
Pageload
The PageSize has a direct impact on the PageLoad – but this mainly affects the way from the server to the client. After that, the pages still have to be displayed in the browser. The loading of data and the structure of the pages happens a bit in parallel and can be influenced by the theme developer. Important data should be transferred first, unimportant later.
For our measurement we used the load time of pingdom – but in the PageSpeed tests you will find a more detailed breakdown – e.g. when the first content was drawn or from when the user can interact with the page.
Simply load everything?
Requests
The number of requests should be kept as low as possible – each request generates additional load. The more files the theme includes, such as media, styles, or scripts, the more requests the client and server need to process.
Intelligent and tidy asset loading through the theme effectively reduces the number of requests required and increases PageSpeed.
100/100 is the goal
PageSpeed
The PageSpeed is a metric that expresses the speed of a website – it asks for numerous criteria that can be met. The maximum achievable value is 100/100.
The first value represents mobile speed, the second represents desktop devices. Since Google has switched indexing to Mobile-First, the first value for mobile devices is decisive for the ranking in the Google index.
Google is constantly increasing the requirements – new technologies are created and at some point assumed. Therefore, don’t wait for optimization – it doesn’t get any better.
Avada
Twenty Twenty
Recommendation
If usability, SEO or the Adwords quality score are important for your website – opt for a WordPress theme that supports you and does not slow you down.
Of course, the final values of your website also depend on the installed plugins, content and media – but here you can control more than the behavior of your theme. The theme forms the basis for the issue of your website. Look for actual modular themes that only deliver what is actually needed.
For technicians
Configuration
For technicians and to make the results comprehensible, here you will find details about the configuration of the PageSpeed test.
We have set up our own instance for this test in our server cloud. At the time of testing, we set up Plesk with Apache+NGINX and PHP 7.4.10. NGINX is especially useful for delivering static files – Apache, on the other hand, takes care of PHP script execution.
In addition, we have set up four test installations for each theme, each with different configurations – so we can compare how dependent a theme is on these optimizations – and where further optimization from the user’s point of view can be made for the respective Theme is no longer worthwhile.
Avada
Last Updated: Theme Version 7.0.2

After theme activation, Avada recommends installing additional plugins. We install the plugins marked “Required”.

We do not install a demo, because otherwise the Pagespeed would no longer be comparable between the different themes – the content would be too different.

Otherwise, we leave the theme at the default settings.
WP-Rocket
At Avada, we had to adjust our WP-Rocket configuration and enable the security mode for jQuery – which causes the loading of this script to delay the further loading of the website. Actually unnecessary, but mandatory with Avada, as it does not integrate some jQuery statements optimally – as attached files – but inline. This results in a Javascript error when inline scripts try to access jQuery if it has not yet been loaded.

As a result, Avada loses an additional 15-30 points in the mobile pagespeed – so this behavior has a pretty big impact on pagespeed.
OceanWP
Last updated: Theme version 1.8.9

After theme activation, OceanWP recommends installing additional plugins. Since most users will follow the recommendation, we will also activate these plugins as part of this test.

Setup Wizard

OceanWP also offers a setup wizard.

We skip the installation of a demo, otherwise the pagespeed would no longer be comparable between the different themes – the content would be too different.

Also on the next page we do not upload logo or icons and do not change the default settings.

This completes the Setup Wizard.
Otherwise, we leave the theme at the default settings.
Twenty Twenty
Last Updated: Theme Version 1.3
No theme settings have been made.
SV100
We will document the configuration settings of our theme at a later date.
Vanilla
We haven’t optimized anything else – only the theme has been installed.
WP-Rocket
The larger your website is, the more important it is to use a caching plugin. We worked for years with various caching plugins, which were however complicated to configure and regularly worked incorrectly – until the plugin WP-Rocket was released. We use this plugin in all our projects and are enthusiastic about the ease of use, stability and outstanding support.
NGINX Optimized
In Plesk it is possible to set additional NGINX directives with the primary admin account. If your web host uses Plesk and does not have access to this form, you should ask your web hoster to set the cache settings accordingly – as this is also possible at the domain level, your web hoster should be able to implement this quickly.
The following NGINX configuration enables compression for static files and increases the browser cache statement to the maximum – ideal for static files. Because WordPress includes files with version numbers in the URL, your website visitors always get up-to-date file versions despite the high cache duration.
# BROWSER CACHE
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain application/javascript application/x-javascript text/xml text/css image/svg+xml;
location ~* \.(css|js|svg)$ {
gzip_vary on;
expires max;
}
location ~* \.(ico|gif|jpe?g|png|eot|otf|woff|woff2|ttf|ogg)$ {
expires max;
}
Code language: PHP (php)
WP-Rocket + NGINX
Combine WP-Rocket with optimized NGINX directives, usually achieve the best result. We use a slightly customized version of the NGINX configuration of Maxime Jobin, which is specially optimized for use together with WP-Rocket.
###################################################################################################
# Rocket-Nginx
#
# Rocket-Nginx is a NGINX configuration to speedup your WordPress
# website with the cache plugin WP-Rocket (http://wp-rocket.me)
#
# Author: Maxime Jobin
# URL: https://github.com/maximejobin/rocket-nginx
#
# Tested with WP-Rocket version: 3.0.5.1
# Tested with NGINX: 1.15 (mainline)
#
# Version 2.1.1
#
###################################################################################################
# Add debug information into header
set $rocket_debug 0;
###################################################################################################
# Do not alter theses values
#
set $rocket_bypass 1; # Should NGINX bypass WordPress and call cache file directly ?
set $rocket_encryption ""; # Is GZIP accepted by client ?
set $rocket_file ""; # Filename to use
set $rocket_is_bypassed "No"; # Header text added to check if the bypass worked or not. Header: X-Rocket-Nginx-Serving-Static
set $rocket_reason ""; # Reason why cache file was not used. If cache file is used, what file was used
set $rocket_https_prefix ""; # HTTPS prefix to use when cached files are using HTTPS
set $rocket_hsts 0; # Is HSTS is off (0) by default. Will be turned on (1) if request is HTTPS
# HSTS value
set $rocket_hsts_value "max-age=31536000; includeSubDomains";
###################################################################################################
# PAGE CACHE
#
# Is GZIP accepted by client ?
if ($http_accept_encoding ~ gzip) {
set $rocket_encryption "_gzip";
}
# Is Brotli accepted by client ?
if ($http_accept_encoding ~ br) {
set $rocket_encryption "";
}
# Is SSL request ?
if ($https = "on") {
set $rocket_https_prefix "-https";
set $rocket_hsts 1;
}
# If HSTS is disabled, unset HSTS set for Rocket-Nginx configuration
if ($rocket_hsts = "0") {
set $rocket_hsts_value "";
}
# File/URL to return IF we must bypass WordPress
# Desktop: index.html or index-https.html
# Mobile: index-mobile.html or index-mobile-https.html
set $rocket_end "/cache/wp-rocket/$http_host/$request_uri/index$rocket_https_prefix.html$rocket_encryption";
set $rocket_url "/wp-content$rocket_end";
set $rocket_file "$document_root/wp-content$rocket_end";
set $rocket_mobile_detection "$document_root/wp-content/cache/wp-rocket/$http_host/$request_uri/.mobile-active";
# Do not bypass if it's a POST request
if ($request_method = POST) {
set $rocket_bypass 0;
set $rocket_reason "POST request";
}
# Do not bypass if arguments are found (e.g. ?page=2)
if ($is_args) {
set $rocket_bypass 0;
set $rocket_reason "Arguments found";
}
# Do not bypass if the site is in maintenance mode
if (-f "$document_root/.maintenance") {
set $rocket_bypass 0;
set $rocket_reason "Maintenance mode";
}
# Do not bypass if one of those cookie if found
# wordpress_logged_in_[hash] : When a user is logged in, this cookie is created (we'd rather let WP-Rocket handle that)
# wp-postpass_[hash] : When a protected post requires a password, this cookie is created.
if ($http_cookie ~* "(wordpress_logged_in_|wp\-postpass_|woocommerce_items_in_cart|woocommerce_cart_hash|wptouch_switch_toogle|comment_author_|comment_author_email_)") {
set $rocket_bypass 0;
set $rocket_reason "Cookie";
}
if (-f "$rocket_mobile_detection") {
set $rocket_bypass 0;
set $rocket_reason "Specific mobile cache activated";
}
# Do not bypass if the cached file does not exist
if (!-f "$rocket_file") {
set $rocket_bypass 0;
set $rocket_reason "File not cached";
}
# If the bypass token is still on, let's bypass WordPress with the cached URL
if ($rocket_bypass = 1) {
set $rocket_is_bypassed "Yes";
set $rocket_reason "$rocket_url";
}
# Clear variables if debug is not needed
if ($rocket_debug = 0) {
set $rocket_reason "";
set $rocket_file "";
}
# If the bypass token is still on, rewrite according to the file linked to the request
if ($rocket_bypass = 1) {
rewrite .* "$rocket_url" last;
}
# Add header to HTML cached files
location ~ /wp-content/cache/wp-rocket/.*html$ {
etag on;
add_header Vary "Accept-Encoding, Cookie";
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header X-Rocket-Nginx-Serving-Static $rocket_is_bypassed;
add_header X-Rocket-Nginx-Reason $rocket_reason;
add_header X-Rocket-Nginx-File $rocket_file;
add_header Strict-Transport-Security "$rocket_hsts_value";
}
# Do not gzip cached files that are already gzipped
location ~ /wp-content/cache/wp-rocket/.*_gzip$ {
etag on;
gzip off;
types {}
default_type text/html;
add_header Content-Encoding gzip;
add_header Vary "Accept-Encoding, Cookie";
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header X-Rocket-Nginx-Serving-Static $rocket_is_bypassed;
add_header X-Rocket-Nginx-Reason $rocket_reason;
add_header X-Rocket-Nginx-File $rocket_file;
add_header Strict-Transport-Security "$rocket_hsts_value";
}
# Debug header (when file is not cached)
add_header X-Rocket-Nginx-Serving-Static $rocket_is_bypassed;
add_header X-Rocket-Nginx-Reason $rocket_reason;
add_header X-Rocket-Nginx-File $rocket_file;
# No HSTS header added here. We suppose it's correctly added in the site configuration
###################################################################################################
# BROWSER CACHE
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain application/javascript application/x-javascript text/xml text/css image/svg+xml;
location ~* \.(ico|gif|jpe?g|png|eot|otf|woff|woff2|ttf|ogg|webp)$ {
etag on;
expires max;
}
Code language: PHP (php)