7 Most Common Website Performance Mistakes
For the past couple of week's, we've been prioritizing work on our client's website performance. When updating old websites, we often find a lot of performance issues. Low website performance costs money by lowering your conversion rates, damaging your brand, and directly impacts your rankings in Google.
I came up with a list of the most common mistakes that we encountered on various websites:
- Poor image optimization
- Fonts causing performance issues
- Overuse of third-party party scripts and widgets
- Disabled server compression
- Lack of server cache
- Outdated or underpowered server
- Unoptimized code
Image optimization can hurt your website badly
One of the biggest mistakes people tend to make is loading unnecessarily large images onto your website. All images for the web should be optimized and, ideally, have exact dimensions as they are displayed. You can use tools like PageSpeed Insights or GTmetrix to efficiently measure website's performance. These tools will help you find problematic images on your website.
Optimizing images can be done in various ways. WordPress supports image sizes. This feature allows you to select a version of the image that's used in the template. You can select image sizes both in the WYSIWYG editor and code templates. You can use the add_image_size()
function, to create additional image sizes in WordPress. The other option is to use a plugin like Easy Image Sizes. It's important to remember that you need to reload images to force WordPress to create new versions of existing images. There's a great plugin for that called - Regenerate Thumbnails.
If your website is using a website builder or is HTML-based without support for resizing images you need to optimize images yourself.
Optimizing images before upload for better site performance
The problem we often encounter is that images are unoptimized before being uploaded to WordPress or other CMS.
Usually, you can leave that to an optimization plugin or script. We had issues with WordPress for optimizing images wider or higher than 10.000px (editorial images). That's why it's always good to preoptimize images before upload. 2500px width or height is the best size, in my opinion, rarely do you need wider/higher images than that.
We've found image optimisation is usually easier on WordPress and Gatsby than other platforms. If you're unsure what CMS your website is running, you can check out this article we wrote on how to tell what platform a website is built on.
If you need much wider images it's worth cropping them as well. For optimizing images before uploading my go-to app is Pixelmator Pro for batch optimization I tend to use ImageOptin, both of these apps are exclusive to macOS. If you're using Windows or Linux check alternatives to ImageOptin. You can substitute Pixelmator with most image editors such as Lightroom or GIMP.
Further image optimization to improve performance
When using a traditional CMS like WordPress you should consider using a plugin for image optimization. WordPress doesn't natively support the .webp
format for images. This new format provides smaller file sizes without compromising the quality of the image. To optimize images on WordPress you can use a plugin like ShortPixel. It will reduce image sizes and provide a .webp
versions of images for newest browsers (check compatibility for .webp format).
The other thing to consider doing is lazy loading images. The lazy load will delay fetching the image until it's visible by the user. WordPress 5.5 and up supports lazy loading natively there's also plugins that can enable that feature for older WordPress versions.
Optimizing images - key takeaways
- Make sure your website uses properly sized images in the content
- Optimize and crop images before uploading
- Optimize images on the server when possible.
Fonts can cause issues with website performance
Using too many fonts or font variants or even the way you load fonts may impact your website performance. On one website, a specific font caused rendering issues with carousels (dropped frames and choppy UX).
Using font hosting services actually has an impact too. Services such as Typekit or Google Fonts make a call to a third party to retrieve that font. There are some cases when adding a font will cause a couple of additional connections to verify the license. This can impact your website's performance.
Optimizing fonts for website performance
There are some ways you can optimize the font loading speed. It's best to serve fonts from your own server using WOFF2
format to load the smallest size possible.
If you can't serve fonts locally there is still a lot you can do. First look at how many fonts and weights are loaded. Loading more than 4 weights (aim for 2-3) and 2 fonts are usually unnecessary.
To check how many fonts are loaded use Developer's Tools in your browser and check the Sources tab to show all files that are loaded.
https://fonts.googleapis.com/css?family=Abril+Fatface|Source+Code+Pro|Source+Sans+Pro:300,400,700,900&display=swap&subset=latin-ext
If using Google Fonts or other font services you can check out the link for implementation. The above link shows that we're probably using too many weights and there's room to reduce the load.
Preloading fonts & using font-display:swap
One more thing that you need to keep in mind is font preloading and using swap property. Why it's important? Your website's rendering won't be blocked by loading fonts.
Browser waits until the font is required, before loading it. With preloading, you're forcing the browser to load the most important fonts immediately. Therefore this should be used only for required assets, not for all (if you're using multiple fonts on different pages). To preload fonts, you need to add link tags to the head of your page.
<link
rel="preload"
href="https://fonts.googleapis.com/css?family=Roboto&display=swap"
as="style"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto&display=swap"
/>
The example above shows how to preload Roboto font from Google Fonts. When preloading local fonts you need to preload them as font
rather than style
.
With the newest change to google's algorithm, it's recommended to use the font-display
descriptor with swap
value. This prevents the browser from not displaying content until the font is loading. Users will see content earlier, but it can be in a fallback font. Google Fonts adds display swap via the URL param &display=swap
. In the case of self-hosted fonts, all you need to do is add font-display: swap;
to the CSS definition of the font.
@font-face {
font-family: 'Abril Fatface';
font-style: normal;
font-weight: 400;
font-display: swap;
...;
}
To optimize the fonts further it's worth considering using system fonts instead. These fonts are always available for visitors and require no additional download. Many large websites like Facebook Github or Instagram actually use system fonts. The downside is the lack of personalization and missing brand typography. That's why it's a difficult choice to make and not often seen.
Fonts optimization key takeaways
- Load necessary fonts only in weights that are used
- When feasible, load fonts from your server
- Use
woff2
format to minimize the size of font files - Preload most important fonts, and use
font-display: swap
to avoid blocking text rendering - Consider using system fonts instead of custom fonts.
3rd party scripts significantly lower the performance of the website
Every 3rd party widget comes with a huge cost to the overall performance of the website. 3rd party scripts are all scripts that are loaded outside of your domain.
Third party scripts include a wide array of different solutions such as:
- Enabling web analytics (e.g. Google Analytics, Facebook Pixel)
- Adding chat widgets (e.g. Facebook)
- Embedding videos (e.g. YouTube, Vimeo)
- Adding social sharing buttons
- Embedding comment systems (e.g. Disqus)
- Embedding ads
- Embedding reviews
It's sometimes hard to avoid them, but you need to measure their impact on the performance of your website to avoid that issue growing out of hand.
Optimizing 3rd party scripts
There's plenty of strategies to handle 3rd party scripts. Paradoxically, the best approach in my opinion is too simple to remove them. If your Facebook chat widget is not used why keep it? You can link to chat instead. The same comes to different tracking scripts. Is Facebook Pixel really needed for your business, maybe one tracking script is enough?
Load scripts where they are needed
The second tactic I use is loading scripts only on pages they are required. Loading comments on the home page seems like a bad idea, the same goes for a calendar widget that is used on one page. Check which plugins are redundant on problematic pages using these tools for monitoring website performance or Chrome Developer Tools.
In WordPress, you can change functions.php to load files only on specific templates by using the code below.
add_action('wp_enqueue_scripts', 'my_theme_load_scripts');
//Load scripts (and/or styles)
function my_theme_load_scripts(){
wp_enqueue_script('jquery');
wp_enqueue_script('my_first_script', get_template_directory_uri() . '/includes/js/my_first_script.js');
wp_enqueue_script('my_second_script', get_template_directory_uri() . '/includes/js/my_second_script.js');
if(is_page()){ //Check if we are viewing a page
global $wp_query;
//Check which template is assigned to current page we are looking at
$template_name = get_post_meta( $wp_query->post->ID, '_wp_page_template', true );
if($template_name == 'slider-portfolio.php'){
//If page is using slider portfolio template then load our slider script
wp_enqueue_script('my_third_script', get_template_directory_uri() .'/includes/js/my_third_script.js');
}
}
}
This will optimize your critical pages that don't require these scripts.
Delay loading of Third-Party Scripts
You can use attributes on script tags in your code to delay loading third-party scripts to speed up initial rendering and decrease blocking time. There are 2 attributes that you can use - async
and defer
.
The async
attribute forces the browser to parse the HTML page while the script is being downloaded. Once the script loads, the code is executed while HTML parsing is paused.
The defer
attribute loads the script after the HTML page is parsed.
If you are using WordPress you can defer scripts using a plugin, or you can use script_loader_tag
filter to add the param yourself by modifying the functions.php
file (WP >= 4.1).
An example to defer Contact Form 7 plugin's script.
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( 'contact-form-7' !== $handle )
return $tag;
return str_replace( ' src', ' defer="defer" src', $tag );
}, 10, 2 );
Organize 3rd party JavaScript with Tag Manager
With a tag manager like GTM (Google Tag Manager) you can optimize all your scripts in one place. Tag managers basically bundle necessary requests into one helping you maintain the better performance of your website.
Scripts with Google Tag Manager are loaded asynchronously which results in websites being rendered without pause. But they still require download and add time to execution so be mindful of how you're using them.
Key takeaways for third-party scripts
- Remove scripts that are not benefiting your business
- Load third-party scripts only on pages that use them
- When possible use
defer
orasync
parameters to load scripts later - If needed use GTM to manage third-party scripts.
Compression and its impact on the website performance
It's possible, but rather rare, that your server is not supporting compression. Compression basically makes files smaller during load. The basic compression technology is Gzip and it's quite rare to find servers that don't support it out of the box. To check if your server uses compression you can use any of tools that check your website performance.
But there's a new kid on the block - Brotli. It's not yet supported in all browsers but has large benefits over Gzip.
- Javascript files compressed with Brotli are ~14% smaller than gzip.
- HTML files are ~21% smaller
- CSS files are ~17% smaller
Check if your site is using Brotli. To support every browser with the best compression you need to use both Brotli and Gzip. Enabling them requires tinkering with servers, and I won't go into that in this article. Although if your hosting provider doesn't support compressions out-of-the-box, it's one of the signs that you might have subpar hosting.
Caching for better website performance
A common solution to all problems with web performance is caching. Caching basically means storing compiled HTML code and returning it instead of dynamically creating the page using server resources.
Efficient caching can dramatically cut the time needed to render pages, but there are some gotchas.
Server Caching
When working with WordPress our first level of caching is OPCache. OPcache compiles PHP code that someone wrote into an optimized version for a server. This occurs when the PHP file executes for the first time. Then, it’s saved to the server’s memory for faster loading at each subsequent page visit. You should be able to turn on OPCache using your hosting provider. On average, OPCaches speeds up WordPress by 300%, at the very least for medium to large sites.
WordPress Caching
The next level of cache is the WordPress cache (not applicable to users not using WP). This cache is compiling pages as HTML files. The idea is that instead of rendering pages on each visit, the server is doing it once, saves them in memory, and then returns these files to visitors. To set up WordPress cache I would suggest you start at the WordPress optimization - cache guide.
This can dramatically improve your WordPress website, but it can also have unwanted consequences. You can see issues page rendering, some HTTP errors, for most pages that are the biggest risk. Unfortunately, if you use other dynamic elements it's possible to break checkouts for membership pages or other widgets so thread carefully.
Browser Caching
The last cache you can leverage is browser caching. It won't help with initial loads but can make the user experience of returning visitors much quicker. The idea behind browser caching is simple when a user downloads a CSS, js file, or image that won't change you can ask the browser to cache it. Instead of being downloaded, it will be loaded from memory.
Enabling browser caching requires changing web server configuration (in the case of WordPress caching plugin will take care of that).
Here's the example for NGINX
location ~* \.(png|jpg|jpeg|gif)$ {
expires 365d;
add_header Cache-Control "public, no-transform";
}
location ~* \.(js|css|pdf|html|swf)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
Here's one for the Apache server
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
Slow servers and their cost to web performance
Optimization is nice, but sometimes your server is the one to blame. The first source of problems might be your web server. To check the webserver I'm using Wappalyzer extension for Chrome.
If you inspect the website you can see which web server your site is using. Apache used to be the most popular web server, but currently, there are more performant options.
Switch webserver to Nginx or LiteSpeed for better performance
Instead of using Apache or IIS, it's worth switching to Nginx (pronounced engine x) or LiteSpeed for better performance. Nginx became a standard over the last couple of years while LiteSpeed is quickly gaining popularity.
Add resources to your server
There are other possible issues with your server. The resources available for your website can simply be not enough. If your site is slowing during peak traffic it's a sign it might be worth updating. We recommend our clients to use either Linode or DigitalOcean for hosting websites.
The other problem might be the location of your server. If your clients are located in Australia you shouldn't use servers located in Europe, this would dramatically extend initial load times.
Use CDN when accessing a global audience
You should also consider adding a CDN on top of your server. CDN stands for content delivery network. CDN's principle is simple it takes content from your original server and copies it onto edge servers. When someone visits your website the content is served from the closest server on the network, which cuts loading times.
We use Cloudflare's CDN to speed up loading websites and images. Most caching plugins for WordPress will help set up the CDN for images too. CDNs are especially important if you're trying to reach a global audience.
Updated PHP to latest version
PHP gets faster with every version. At the time of writing the lowest PHP version supported is PHP 7.3, check the currently supported PHP versions. This would mean that 49.89% of PHP websites use outdated versions as of May 2020. Using an unsupported PHP version is a huge security issue and it leaves performance on the table.
Updating the PHP version can cause issues with older code when some functions get deprecated along the way. Updating your PHP to the latest versions improves both safety and performance.
Unoptimized code and its cost to web performance
The last and most problematic performance issue is the code itself. It's not uncommon to have bloated JS or CSS that's not minified.
This problem is especially visible on WordPress websites using large themes. If your website is based on a huge theme 50% of the code loaded may be actually unnecessary.
Even using custom themes the problem can still be present. Your JS/CSS may use old polyfills that are no longer required, or not be minified at all. With WordPress, this issue can be somewhat solved by optimization plugins that can minify code. Unfortunately, it's not uncommon to have issues with styles and interactions after enabling such plugins.
The other problem, not always present, lays in the backend code. There might be slow queries somewhere in your codebase, deprecated functions, or other issues that degrade the performance of your website.
There are basically 3 solutions to that problem, switching themes if you are using WordPress, hiring someone to check for possible issues, or redoing the website altogether.
At Clean Commit we build websites with performance in mind. If you feel like you need to update your website, check our website pricing guide or reach out to schedule a conversation.