General Guidelines to Improve Your Website Speed

Last Updated on February 12, 2021

Back before 2010, when the internet began to be widely used. Commonly, ordinary people only use email, social media, or just surfing in search engines. I use a search engine only to help complete my work. However, there aren’t many relevant choices in the search results. At this time, the website speed is not so considered. As a result, while reading other websites, I opened some search results links and left them for a while. Then I may open it after reading the current website. Or, if the content seems very relevant, I’ll open it in a minute. If I’m out of luck, even within 10 minutes some links won’t show anything.

Today, almost all internet users won’t wait for the loading of any pages. They want an instant load. Indeed they still have tolerance, but no more than 2-5 seconds.​[1]​ Else, they will find another website with similar content. Therefore, the loading speed of a website is the first impression to the users.

Mobile phone domination

People indeed say most of the time users use their mobile phones to access the internet.​[2]​ I saw the facts on the analytics of my blog, see it in Figure 1 below. Then, it creates another issue. In general, the average mobile performance is far below the desktop performance.​[3]​ Therefore, this will make the web page load slower in the mobile than the desktop.

My blog's visitors in the last 3 months of 2019
Figure 1. My blog’s visitors in the last 3 months of 2019

It also applied to our website. When you are trying the best to build your website contents, sometimes you will also enhance the appearance of your website. It will make your visitor feel comfortable. Then, you find it builds up some visitors for several days, weeks, or maybe a month. Slow and steady, until you realize the traffic is starting to go down. Some webmaster tools notify you that your website is performing poorly, and your visitors are not coming back. And Yes! one reason is most likely that your website is way too slow.

So, if that becomes part of your problem, I will give you some recommendations to speed up your website. Maybe some parts need technical knowledge. But I’ll try to write it as simply as possible.

Check your website speed performance

Before starting to fix your website, first, you need to know your website performance. You can use some online web performance tools such as PageSpeed Insights, GTMetrix, Pingdom, or other similar tools. For offline tools, you can use Audit in the developer tools of Chrome Browser.

In PageSpeed Insights or Chrome’s Audit, you need to focus on mobile performance. Hence, it will give you better diagnostics. Because sometimes, I get 99-100 scores on desktop performance but only get 50-70 scores on mobile.

Example of website speed in PageSpeed Insights result (or Chrome audit)
Figure 2. Example of PageSpeed Insights result (or Chrome audit)

Figure 2 above shows you the example of web performance metrics. To get the best result, First Contentful Paint and Meaningful Paint should be equal or below 2.3 seconds, and the others should be below 3.3 seconds. But for Max Potential First Input Delay, it should equal or below 130 ms.​[4]​

Then what does it mean? it means your website should complete the loading process in a maximum of 2-3 seconds. First Contentful Paint (FCP) and First Meaningful Paint (FMP) are the most important things. It shows when the user can start reading the content.

Scroll down to the diagnostic details, and you will find the reason for bad loading performance. In figure 3 below, the diagnostics for each website may vary. Even on the very same website, sometimes different pages have different diagnostic results.

Example of PageSpeed Insights diagnostics results
Figure 3. Example of PageSpeed Insights diagnostics results

For a detailed version, you can even open the details of each performance. So, you can focus on fixing those performances.

Backup your website first!

Before trying to improve your website speed, you have to back up your website. This is not optional, but mandatory. All of your content, customization, or modification on your website could be lost in a matter of seconds. So, if that happens (I hope not!), you only need to restore from the latest backup.

1. Optimize template, widget, and plugin

Okay, before you go through the harder part, maybe a little effort could improve the performance drastically. I hope so!

If you’re using CMS such as WordPress, Joomla, or even Blogger, your template, widgets, and plugins are probably the biggest contributors to the website’s poor performance. The easiest way is to open some of your web pages, check if your website loads many objects and widgets. Those objects include sections, images, rectangles, or anything that you can see clearly on the page, and don’t forget some animations that might appear on the screen.

The more objects displayed on the page, the worse the performance will be, for sure. If your template uses too many objects, widgets, and animations, then you may want to change your template.

Choose minimalist, lightweight, or AMP template

If you’re using Blogger/Blogspot, the easiest way is to use the default Blogger templates. The default templates from Blogger are generally lightweight and responsive.

Accelerated Mobile Pages (AMP) features in Blogger templates give much better performance on mobile phones than non-AMP templates ​[5]​. However, Blogger has not provided any AMP version of the default template yet. If you want a template that supports AMP, you can search/buy it from a third party developer. Besides, you can also modify the template that you are using to support AMP features, by following the guidelines from the AMP developer. To check whether the template you are using meets the AMP criteria, you can visit the AMP Project website.

If you are using WordPress, Joomla, or other CMS, then make sure you’re looking for minimalist or lightweight templates. Choose the template which has fewer objects such as social icons, sliders, widgets, animations, or other eye-catching elements displayed on. Maybe you also need to consider whether you need to use animation. In my opinion, animation on most web pages is not very important, unless your website sells graphics or animation.

Besides, if you want AMP support on your WordPress site, the AMP developers also offer the official AMP plugin for WordPress. In fact, there are many wordpress templates from third parties that support AMP.

Reduce the number of widgets

Other than the template, too many widgets also reduce the loading performance. Hence, you need to use widgets as little as you can. For each widget installed, you need to consider whether it is a nice-to-have widget or must-have widget. Anything that is not must-have widgets should not be used.

Use the must-have widgets like the search bar, categories, and recent posts. Other than that, consider being deleted, unless your visitors depend on it. Oh, and you should be aware that visitors may only open your web page for content, they never look for widgets.

Limit the number of plugins

When working with CMS like WordPress, Joomla, or similar, the plugins surely help us a lot. From the cache, image optimizer, minification, and many more plugins may be installed on our website. These additional features and functionality help the owner developing the website. But, that comes at a price, website speed. The more plugins installed, the slower the website will be. So, choose the most essential plugin to maintain the optimum website performance. Put quality and performance over the others.​[6]​

2. Use LiteSpeed web server

Litespeed web server has proven its performance beyond other web servers such as Apache or Nginx.​[7], [8]​ If your web hosting only uses Apache or Nginx, and has slow performance, you may need to migrate to another web hosting.

If you don’t know what type of your web server, try using dnschecker.org or browserspy.dk to find the information about your web server.

LiteSpeed Cache for WordPress (LSCWP)

For WordPress users, the LiteSpeed Cache plugin is a must-have plugin to improve your website speed performance. It handles many improvements, such as caching, minifying, image optimization, and many more, all for free.

In my experience on WordPress cache plugin, the LiteSpeed Cache plugin outperforms other similar plugins, even with those paid plugins. Even more, this plugin gives you extra features like Image Optimization.

The image optimization will process your images in their server, then send them back to your server for storage. Hence you don’t need to pay for another unnecessary image storage server. But its drawback is you may run out of space if you upload too many images to your WordPress. Therefore, you need to double-check your web hosting budget to match your needs.

3. Enable cache

When a browser requests a web page, it is sent to the server. Then a server doing some complex calculations, generating header, content, footer, etc. Then deliver the web page result to the browser. This is what the normal browser-server interaction.

Web caching is one of the most important features to have. For example, this page you’re reading may be requested by other users/browsers. But the content will be the same. So, with the web caching, the server does not need to repeat all the complexity of these calculations. But just deliver the web page result from the last calculation. That’s what web caching does.​[9]​

Today web caching technology is smarter. When the administrator changes something to the page, web caching will delete the last cache, and then automatically recalculate the page.

Therefore, caching may not improve your PageSpeed Insights, GTMetrix, or Pingdom scores too much. But this is another website speed improvement. It will reduce the server load and increase the SEO scores.

For CMS users, like WordPress or similar, there are many web caching plugins out there. Then, just install one of them, and enable it. For blogger users, there is no web cache plugin. But I believe that Google already uses web caching in their server. So don’t worry about it.

4. Use CDN

The content delivery network (CDN) is used to distribute content to some servers in several countries in the world. In general, the distance from the server to the location of visitors is one of the factors of website speed. In this case, the CDN is very helpful in increasing the website speed. By using a CDN, visitors will get the same content from the server closest to their location.

However, if you are using local languages, or such as your server is in Jakarta and your target audience is only for Indonesia. Thus, the loading speed of your website might not be much different by using a CDN. In this case, the CDN will only help reduce your server’s load.

The use of CDN will have many positive impacts if the target audiences are the people around the world. Besides speeding up page loading, the CDN will also help reduce the server’s load.

Free CDN

Today, many free CDNs are starting to offer awesome features, for example, Cloudflare, Quic.cloud, Jetpack site accelerator (Proton), etc.

Cloudflare is the most widely used by site admins as a free CDN.​[10]​ With easy installation, and complete basic features offered for free, it’s no wonder Cloudflare becomes the site manager’s first choice.

Jetpack site accelerator is also a free CDN. But this CDN is specifically for Jetpack plugin users, with the WordPress CMS. So to use it, you must install the Jetpack plugin on your WordPress. Similar to the Jetpack site accelerator, Quic.cloud is also a free CDN for WordPress, using the Litespeed plugin.

Google Hosted Libraries

Besides using CDNs for your site files, Google Hosted Libraries also provide common library files needed by the site. These common files such as JQuery, Web Font Loader, D3.js, and other library files. So if your site needs some of these common libraries to load the pages, you can simply call the file from the google server.​[11]​

For example, if you need a JQuery file, then you just need to include the following code on your HTML page:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

5. Optimize images

The majority of users who read articles, blogs, or any content, they tend to understand better with images explanation. Therefore, some of our web pages may have many images on a single page. But, it surely will affect our website speed. So, the first thing is, you need to use fewer images as possible.

Compress the image size

Other than that, every image used in a website may need to be optimized. Reduce the image’s file size as small as possible, without reducing too much quality. This could be done by one of these:

  • offline tools on desktop using some free image compressor like Caesium, ImageOptim, or other similar offline tools.
  • online tools such as TinyPNG, Compressor.io, or other similar online tools.
  • or, if you’re using WordPress on the LiteSpeed Web Server, consider using LS Image Optimizer.

Using WebP extension

The average size of WebP images is much smaller than optimized JPEG or PNG. If you don’t have any plugin or tools in your web server, you can manually convert your images with online-convert.com.

Google’s WebP image format was released in 2010.​[12]​ But even in this 2020, many websites are not using WebP for their images. Even though Image size (byte) using this format is most likely much smaller than JPEG or PNG. This happens because some old browsers did not support WebP. Until 2021, nearly 10.87% of global users can’t open WebP on their browsers.​[13]​

Even though they are only 10.87%, you couldn’t ignore them to get the fastest speed. As a content provider, you still need to serve the jpg/png version on unsupported browsers.​[14]​ Some of you may need some javascript or CSS to serve non-WebP images to the old browser. This is the hardcoding way to provide WebP images but still serve png/jpg images on unsupported browsers. But don’t worry, some libraries could help you detect the browser and serve WebP or non-WebP images. Those libraries include Modernizr, WebPJS, or Picturefill.​[15]​

Hey, you’re lucky if you’re using WordPress on the LiteSpeed Web Server. You only need the Image Optimization feature of the LiteSpeed Cache plugin. Then, enable the “Request WebP versions” in its setting. It will do all the work, even serve non-WebP images to unsupported browsers.

Test your WebP switch on an unsupported browser

Sometimes you need to make sure that your page serves WebP images on a modern browser. But you also need to try it to serve non-WebP images on an unsupported browser. If you run on Windows, you can use Edge’s F12 Emulation (Edge’s developer tool > emulation). Then you can select Internet Explorer 11 in user agents to simulate your web pages in the older version of Internet Explorer.​[16]​

6. Defer the offscreen images

Normally, an article page height is longer than the browser display. The display is even smaller on the mobile phone. Hence, when visitors load an article page, they may only see one or several image(s) at a time. The images below the display are called offscreen images. Let’s take a look at figure 4 below.

Normal and lazy loading on images
Figure 4. Normal and lazy loading on images​[17]​

Let’s say you have a page that has 4 images and around 500kb each image. Then, visitors could only see 2 of them at a time on their mobile phone. In the normal loading or without optimization, all images are loaded at the same time. Hence, the initial page load will require 2 Megabytes.

Here you can use optimization to postpone the loading of the offscreen images. And let the images load when visitors scroll down to see them. It is called Lazy loading. So, if the browser could only see 2 images, then images 1 and 2 will load first. Then, if the user scrolls down to see image 3, load them right away. Therefore, the initial load only requires 1 Megabyte.

For WordPress users, usually, any image optimizer plugin provides a lazy loading feature, you could enable it.

Using lazysizes javascript library

You also could add a lazy loading feature manually on your HTML website by using javascript. Here you can use Lazysizes library from Alexander Farkas​[18]​ ​which has already been improved by Adhy Suryadi​[19]​. You can copy the code below and paste on your website before the end of </body>.

<!-- Defer offscreen images and videos -->
<script async='async' src='https://cdn.rawgit.com/aFarkas/lazysizes/gh-pages/lazysizes.min.js' type='text/javascript'></script>

<!-- auto adds attribute class="lazyload", src, and data-src -->
<script>
//<![CDATA[
for(var imgEl=document.getElementsByTagName("img"),i=0;i<imgEl.length;i++)imgEl[i].getAttribute("src")&&(imgEl[i].setAttribute("data-src",imgEl[i].getAttribute("src")),imgEl[i].className+=" lazyload",imgEl[i].setAttribute("src","data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="));

function wrap(top, selector, bottom) {
var videos = document.querySelectorAll(selector);
    for (var i = 0; i < videos.length; i++) {
        if (videos[i].getAttribute('src')) {
            videos[i].setAttribute('data-src', videos[i].getAttribute('src'));
            videos[i].removeAttribute('src');
        }
        videos[i].setAttribute("class","lazyload");
        videos[i].setAttribute("style", "position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; border: 0px;");
        var modified = top + videos[i].outerHTML + bottom;
        videos[i].outerHTML = modified;
    }
}
wrap("<div style='position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:0 auto;width:100%'>", "iframe[src*='youtube.com']", "</div>");
//]]>
</script>

This code is pure javascript, without the need for jQuery. It will use the lazysizes library to run the lazy load. Moreover, the modified code above will automatically search all images and iframe tags, so the lazysizes can work. It will add some attributes like class="lazyload", src, and data-src. Therefore, you only need to copy and paste it into your page and let it do the work for you.

7. Reduce Javascript and CSS

As stated before, you need to minimize the objects on the front page, as few as possible. Sometimes dynamic objects use too many Javascript or CSS on our website. Hence, it makes a beautiful website but is as slow as a snail.

Then, you may minimize or even remove unnecessary javascript and CSS. For WordPress users, you can use the LiteSpeed Cache plugin or another caching or optimizer plugin to automatically minify your JS and CSS. If you need a manual way for JS/CSS, you can use minifier.org. You may even minify your HTML to increase your website speed.

On the other hand, removing unnecessary JS and its objects is much better than minifications. For example, if you have a “reading progress bar“, I recommend you to remove it. Hey pal, you have a scroll bar, isn’t that enough? Unless your scroll bar is hidden or auto-hide.​[20]​

By the way, I don’t recommend you to find unused CSS using online tools out there. Most of the time, you will ruin your website design. Unless you want to use paid tools, but it also does not guarantee 100% success.​[21]​

But I remind you to double-check for each modification on your website. This includes the minifications or removing JS/CSS.

8. Defer render-blocking CSS/JS

Any CSS and JavaScript need to download before they can be used and block another rendering process, could be categorized as render-blocking resources. Too many render-blocking resources will slow down the rendering page. There are some methods to postpone this issue. But before you do something, please backup your website first!

Usually, the render-blocking CSS/JS is located inside <head> </head>. For example:

<head>
    ...
    <script type="text/javascript" src="js/mycode.js"></script>
    <link href='css/bootstrap.min.css' rel='stylesheet'/>
    <link href='css/font-awesome.min.css' rel='stylesheet'/>
    ...
</head>

There are two solutions to solve this problem.​[22]​ The first solution, you can move them into the bottom of your HTML, just before </body>. Especially if you use Font Awesome or similar. And for the <script> tag, you can add defer or async attributes to optimize them. But the defer and async attributes must not be specified if the src attribute is not present. For example, the script will be:

<script defer="defer" async="async" type="text/javascript" src="js/mycode.js"></script>

But in my experience, these solutions may ruin the website styles and features. Especially, when modifying the link of jQuery and bootstrap. Therefore, for each <script> or <link> you modify, you need to double-check whether all of the features on your website are still working. If something is wrong on your website, you can remove the defer and async attributes in your last modified tags.

The other solution is only adding rel="preload" attribute inside the <link>, without the need to move it into the bottom of your HTML. Here’s the example:

<link rel="preload" id="stylesheet" href="css/bootstrap.min.css" as="style" onload="this.onload=null; this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="css/bootstrap.min.css"></noscript>

But there is a drawback with this second method. Only a few browsers can run this attribute, other browsers sometimes disable it in the default. Therefore, you need to add this polyfill in the bottom just before </body>:​[23]​

<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(a){"use strict";var b=function(b,c,d){function e(a){return h.body?a():void setTimeout(function(){e(a)})}function f(){i.addEventListener&&i.removeEventListener("load",f),i.media=d||"all"}var g,h=a.document,i=h.createElement("link");if(c)g=c;else{var j=(h.body||h.getElementsByTagName("head")[0]).childNodes;g=j[j.length-1]}var k=h.styleSheets;i.rel="stylesheet",i.href=b,i.media="only x",e(function(){g.parentNode.insertBefore(i,c?g:g.nextSibling)});var l=function(a){for(var b=i.href,c=k.length;c--;)if(k[c].href===b)return a();setTimeout(function(){l(a)})};return i.addEventListener&&i.addEventListener("load",f),i.onloadcssdefined=l,l(f),i};"undefined"!=typeof exports?exports.loadCSS=b:a.loadCSS=b}("undefined"!=typeof global?global:this);

/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
!function(a){if(a.loadCSS){var b=loadCSS.relpreload={};if(b.support=function(){try{return a.document.createElement("link").relList.supports("preload")}catch(b){return!1}},b.poly=function(){for(var b=a.document.getElementsByTagName("link"),c=0;c<b.length;c++){var d=b[c];"preload"===d.rel&&"style"===d.getAttribute("as")&&(a.loadCSS(d.href,d,d.getAttribute("media")),d.rel=null)}},!b.support()){b.poly();var c=a.setInterval(b.poly,300);a.addEventListener&&a.addEventListener("load",function(){b.poly(),a.clearInterval(c)}),a.attachEvent&&a.attachEvent("onload",function(){a.clearInterval(c)})}}}(this);
</script>

9. Using preconnect or dns-prefetch

Sometimes when rendering a page, our website uses several resources from external domains. At that time, the browser needs to “connect” to external servers before it can receive a response.​[24]​ This connection consists of several steps: DNS lookup, TCP three-way handshake, TLS handshake, and HTTP Request. If there are many external domains listed, these steps need time to performs and may increase the loading time.​[25]​

You could improve the loading performance by making a browser connect earlier to the external domain. Commonly, you could use one of the defined relationship types such as dns-prefetch or preconnect in the HTML <link> element.​[26]​

To define dns-prefetch or preconnect, you can write it as follow:

<link rel="dns-prefetch" href="//externaldomain1.com">

or

<link rel="preconnect" href="//externaldomain1.com">

As you can see, it doesn’t need to write the absolute URL, but you can use a protocol-relative URL.

Deciding relationship type

So, which one do you need to use? dns-prefetch or preconnect, or both?

The dns-prefetch, as it names, only does the DNS Lookup then stores it in the cache. Wherein preconnect, do the DNS lookup, TCP three-way handshake, TLS handshake. DNS lookup only needs a simple query, whereas TCP and TLS need to use some server resources.​[27]​

If the resource is required on each load, and the browser does not store it in the cache, you could use preconnect. This connection will be open for less than 10 seconds.

But when the resource is static like CSS or JS, it is likely to be cacheable. Then using preconnect could open unnecessary TCP and TLS to the server. So do not overuse the preconnect feature. Use preconnect only for important resources, and you can use dns-prefetch instead for the rest of your resources.​[24]​

Other than that, you can use dns-prefetch as a fallback of preconnect on any unsupported browser. To do that, write the <link> element twice only for preconnect domains as follow:

<link rel="preconnect" href="//externaldomain1.com">
<link rel="dns-prefetch" href="//externaldomain1.com">

It’s recommended to use dns-prefetch and preconnect in separated <link>. Avoid using rel="preconnect dns-prefetch" as it may cause a bug in Safari/WebKit. It will not preconnect to the origin, because assumes a single value on the rel attribute.​[28]​

Defining external URL

Before you could use dns-prefetch or preconnect, you need to list all of your external domain requirements. You can use the browser “inspection” tool to find all of your external resources, as seen in Figure 5. If you can’t find it, right-click and add the domain column in its table header bar.

Find the list of external domains
Figure 5. Find the list of external domains

After you finish writing down all the external domains, add dns-prefetch or preconnect with the external domains at the beginning of <head> element as follows:

<head>
    <link rel="preconnect" href="//google-analytics.com">
    <link rel="dns-prefetch" href="//google-analytics.com">

    <link rel="preconnect" href="//externaldomain1.com">
    <link rel="dns-prefetch" href="//externaldomain1.com">

    <link rel="dns-prefetch" href="//ajax.googleapis.com">
    <link rel="dns-prefetch" href="//example.com">
    <link rel="dns-prefetch" href="//myseconddomain.com">
    <link rel="dns-prefetch" href="//anotherdomain.com">
    ...
    ...
</head>

10. Defer Adsense loading

I believe many of you already install Google Adsense on your websites. Well, I will tell you something. Here’s the fact, no matter how fast your website speed, adding Google Adsense will drop your speed performance. Moreover, it could be 2 to 5 times slower (or even more) than without Adsense.

Before you optimize the Adsense, you need to know the structure of the ad unit code. For each Adsense unit code, it could be divided into 3 parts. Let’s call it “Ads JS library“, “Ads Unit Identifier“, and “Ads load command“.

The Ads JS library is the main code of the Adsense itself. All the Adsense functions are included here. For each web page, you only need one of them.

Then, the Ads Unit Identifier will tell Google where and how the ads will load. This unit identifier is the place where you want an ad to appear. If you want to show 2 ads, then you need to copy this identifier twice (e.g. in header and sidebar)

And the last, Ads load command is a caller to get the ads. The number of this command should be the same as the number of Ads Unit Identifiers.

See the structure of ad unit code below:

<!-- Init Ads JS library -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

<!-- Ads Unit Identifier -->
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
     data-ad-slot="1234567890"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>

<!-- Init Ads load command -->
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>

So, to optimize this ad unit code, you need to defer both “Ads JS library” and “Ads load command“. What I mean is, you need to run both after the initial page load completes, and the user starts to interact (scroll) with the page.

There is some code out there to build a lazy load for Adsense. But not good enough, especially if using Auto ads enabled. So, I combine and modify some recommendations out there to match my requirements. Thanks to bungfrangki​[29]​ and Erik Engi​[30]​ who provide the initial code, so I could modify it.

Website speed vs conversion

Before you use this optimization, you have to know what’s the impact. Your website speed will increase at the expense of Adsense impression, which will be reduced.

The user experience will be better if you improve the website speed. But we all know the one that cuts the speed is the Adsense itself.​[31]​ So you may choose whether to keep as it is or change it. If you are okay with that improvement impact, you can optimize your Adsense.

The lazy load adsense code

First, the important things, find and remove both “Init Ads JS library” and “Init Ads load command” from all the ad unit code structures written in your HTML code. If you display more than 1 Adsense unit code, please remove both “Init Ads JS library” and “Init Ads load command” from all of them.

So, every Adsense code that has been installed, leave the Ads Unit Identifier to stay in the body or widget. This part does not need to be deleted, leave it untouched. So the code will be like the following code:

<!-- Init Ads JS library -->
<!-- deleted -->

<!-- Ads Unit Identifier -->
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
     data-ad-slot="1234567890"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>

<!-- Init Ads load command -->
<!-- deleted -->

After that, please copy the code below to the end of your HTML, just before </body>.

<!-- Defer Ads JS library -->
<script type='text/javascript'>
//<![CDATA[
/* Lazy Load AdSense*/
var lazyadsense = !1;
window.addEventListener("scroll", function() {
    (0 != document.documentElement.scrollTop && !1 === lazyadsense || 0 != document.body.scrollTop && !1 === lazyadsense) && (! function() {
        var e = document.createElement("script");
        e.id = "g_ads_js", e.type = "text/javascript", e.async = "async", e.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js";
        var a = document.getElementsByTagName("script")[0];
        a.parentNode.insertBefore(e, a)

      	/* only for AdSense Auto ads*/
      	var gads = document.getElementById("g_ads_js")
        gads.setAttribute("data-ad-client", "ca-pub-XXXXXXXXXXXXXXXX");

    }(), lazyadsense = !0)
}, !0);
//]]>
</script>

<!-- Defer Ads load command -->
<script>
    (adsbygoogle = window.adsbygoogle || []).onload = function () {
        [].forEach.call(document.getElementsByClassName('adsbygoogle'), function () {
            adsbygoogle.push({})
        })
    }
</script>

Please take a look at Line 13 and 14 above. If you enable Auto ads in your Adsense site setting​[32]​, then you need to change “ca-pub-XXXXXXXXXX” with your Adsense ID. Or else, if you disable your Auto ads, then you need to remove both lines (lines 13 and 14).

After that, please double-check your website. Make sure the Adsense starts loading when you start scrolling the page.

Fix for cumulative layout shift

The updated Google algorithm on 2020/05/18 began to consider any changes in the initial location of HTML elements after the page loaded. This location change is then referred to as a cumulative layout shift (CLS). Then any changes in the initial location of the HTML elements, could have an impact on the SERP score of the page. But any changes that are intended by the user do not affect the CLS.

So by using the code for Google Adsense lazy load above, even though it increases the website speed, at first, it will harm the CLS. Because before Adsense is loaded, an HTML element where Adsense is located has 0px height. But after the AdSense ads are loaded, the height of the element will change to around 280px. Automatically, the initial location of all elements below that Adsense will be moved down. This could make the CLS score more than 0.5. Even though the maximum value suggested is no more than 0.25.

Therefore, it is necessary to change the code structure above. Search all of your Ads Unit Identifier, then add the <div> element (lines 1 and 15) as in the following code:

<div style="min-height: 280px;">
     <!-- Init Ads JS library -->
     <!-- deleted -->

     <!-- Ads Unit Identifier -->
     <ins class="adsbygoogle"
          style="display:block"
          data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
          data-ad-slot="1234567890"
          data-ad-format="auto"
          data-full-width-responsive="true"></ins>

     <!-- Init Ads load command -->
     <!-- deleted -->
</div>

But wait, if you use an unresponsive Ads Unit, means that the dimensions is fixed, then the minimum height of <div> above must be adjusted to the height value of the Ads Unit. Suppose you have a 728x120 px Ads Unit, then your <div> height should be <div style = "min-height: 120px;">, as in the following code:

<div style="min-height: 120px;">
     <!-- Ads Unit Identifier -->
     <ins class="adsbygoogle"
          style="display:inline-block; width:728px; height:120px"
          data-ad-client="ca-pub-XXXXXXXXXXXXXXXX"
          data-ad-slot="1234567890"></ins>
</div>

Note: at this time, if you ONLY use auto ads, there will be no Ads Unit Identifier code installed. So I still don’t get any solution if the CLS value is too high because of lazy load Adsense. If that happens, then remove the lazy load Adsense code, and use the original auto ads code.

11. Reduce DOM element

To simplify, Document Object Model (DOM) is the element that makes up the structure of the HTML or XML document. if you know the element of the HTML, such as HEAD, BODY, DIV, those are DOM.​[33]​

When I write <div> content </div>, that is 1 DOM. So, to make it simple, the code below has 6 DOMs.

<!DOCTYPE html>
<html>
    <head>
        <title>page title</title>
    </head>
    <body>
        <h1>The title</h1>
        <p>this is the content</p>
    </body>
</html> 

To make you understand better about the code above, the HTML is the first level of depth, the HEAD is the second depth, and the TITLE is the third. Then for example BODY, it has 2 children, which are H1 and P.

To speed up a web page, use as few DOM as possible. In the PageSpeed Insights, the recommended DOM is around 1500. Then with a maximum 32 depth, and one DOM has the child less than 60.​[34]​

DOM reduction case example

Then how does this guide help you reduce the DOM? Okay, take a look at my other web page. In the beginning, it has nearly 2000 DOMs. Scroll it to the bottom until you see the comments. It has more than 90 comments.

A block of comment before optimization which cut website speed
Figure 6. A block of comment before optimization

And before optimization, it has around 18 DOM for each comment. Take a look at its comment structure below (before optimization):

<?php /* loop till display all comments */
for ($x = 0; $x < numComments; $x++) { ?>

<li class="comment odd" id="<?php $commentId?>">
    <article class="comment-body">
        <footer class="comment-meta">
            <div class="comment-author xcard">
                <noscript>
                    <?php $profileImage?>
                </noscript>
                <?php $lazyProfileImage?>
                <b> 
                    <span> 
                        <span class="user"> <?php $username?></span> 
                    </span> 
                </b>
            </div>
            <div class="comment-metadata">
                <a href="#<?php $commentId?>">
                    <time datetime="<?php $commentDate?>">
                        <?php $commentDate?>
                    </time>
                </a>
            </div>
        </footer>
        <div class="comment-content">
            <p>
                <?php $commentContent?><br/>
            </p>
        </div>
        <div class="reply_button">
            <span class="comment-actions secondary-text">
                <a class="smoothscroll comment-reply-link" href="#">
                    <i class="fa fa-reply"></i>
                </a>
            </span>
        </div>
    </article>
</li>

<?php } ?>

In the server, initially, it only has 41 lines to display all the comments. So, then I have to remove as many unnecessary DOMs as possible.

For example, in lines 12 to 16, there are unnecessary B and SPAN with no class, I can remove it. Then leaving only <span class="user"> <?php $username?></span> there.

All I do is remove other unnecessary HTML elements, but without changing the final result. So here the example of optimized comment block:

<?php /* loop to display each comments */
for ($x = 0; $x < numComments; $x++) { ?>

<li class="comment odd" id="<?php $commentId?>">
    <noscript>
        <?php $profileImage?>
    </noscript>
    <?php $lazyProfileImage?>
    <span class="user"> <?php $username?></span>
    <br>
    <a class="comment-metadata" href="#<?php $commentId?>">
        <time datetime="<?php $commentDate?>">
            <?php $commentDate?>
        </time>
    </a>
    <?php $commentContent?><br/>
    <a class="smoothscroll comment-reply-link" href="#">
        <i class="fa fa-reply"></i>  Reply
    </a>
</li>

This optimized comment block leaves only around 10 DOM. So I already reduce more than one third. Then, take a look at the result below:

A comment after optimization to increase website speed
Figure 7. A comment after optimization

As you can compare between Figure 6 and Figure 7, there are no significant changes. Maybe just a different reply button, but many DOMs have been removed. Hence will increase the website speed. Even though you can only feel it if there are many comments.

12. Lazy load for comments

The website’s engagement could be improved with the comment section on each web page. It could make visitors return to your page.​[35]​

Sometimes, when your page has many daily visitors, most likely there will be a lot of comments. For example on this web page, or most likely when you use an e-commerce website. But, too many comments will reduce your website speed. It will do many HTTP requests.

Therefore, to speed up the web load, you could postpone the loading of comments. The idea is to start loading the comment when the user clicks the comment section. If you’re using WordPress, you could use some plugins like Lazy load for comment or other similar plugins.

If you’re using Blogger, you can change the setting. Open the Settings > Post, comment and sharing > Comments. then change Comment Location to Full page or Popup window. See Figure 8 below for the details.

Changing blogger comment setting
Figure 8. Changing blogger comment setting

Final words

That’s great if you read this line. I hope this guideline could help improve your website speed. If you think that this guideline is helpful, you can share it with your friend or colleague. If you have something in your mind, you could leave a comment here, feel free to go to our Facebook page.

References

  1. [1]
    WP Engine, “Every second count: How page performance and speed affect your business, and your bottom line,” WP Engine, 2016. https://wpengine.com/wp-content/uploads/2016/05/WP-EBK-PageSpeed-v03-PUB.pdf (accessed Jan. 21, 2020).
  2. [2]
    StatCounter, “Mobile and tablet internet usage exceeds desktop for first time worldwide,” StatCounter, Nov. 01, 2016. https://gs.statcounter.com/press/mobile-and-tablet-internet-usage-exceeds-desktop-for-first-time-worldwide (accessed Jan. 25, 2020).
  3. [3]
    Computer Hope, “Computer vs. smartphone,” Computer Hope, Aug. 02, 2019. https://www.computerhope.com/issues/ch001398.htm (accessed Jan. 25, 2020).
  4. [4]
    Google Developers, “About PageSpeed Insights,” PageSpeed Insights: Make your web pages fast on all devices, Dec. 02, 2019. https://developers.google.com/speed/docs/insights/v5/about#faq (accessed Jan. 25, 2020).
  5. [5]
    B. Mondal, “10 Effective Tips To Speed Up Blogger Blog,” Prootips, Jan. 15, 2020. https://prootips.com/effective-tips-to-speed-up-blogger-blog/ (accessed Jan. 25, 2020).
  6. [6]
    Kinsta, “A Beginner’s Guide to Website Speed Optimization,” Kinsta, Dec. 15, 2019. https://kinsta.com/learn/page-speed/ (accessed Jan. 28, 2020).
  7. [7]
    L. Clarke, “Benchmarks: OpenLiteSpeed vs. NGiNX vs. Apache,” LiteSpeed Blog, Mar. 05, 2018. https://blog.litespeedtech.com/2018/03/05/compare-openlitespeed-to-nginx-and-apache/ (accessed Jan. 26, 2020).
  8. [8]
    G. Varghese, “OpenLiteSpeed vs Nginx in WordPress – TTFB, Load Time, Stress Test Results,” WP Speed Matters, Jun. 14, 2019. https://wpspeedmatters.com/openlitespeed-vs-nginx-in-wordpress/ (accessed Jan. 26, 2020).
  9. [9]
    D. Pataki, “What is Website Caching and Why is it so Important? ,” Winning WordPress, Jan. 28, 2020. https://winningwp.com/what-is-website-caching-and-why-is-it-so-important/ (accessed Jan. 28, 2020).
  10. [10]
    Datanyze, “Market Share Category: Content Delivery Networks,” Datanyze. https://www.datanyze.com/market-share/cdn–10 (accessed Jun. 21, 2020).
  11. [11]
    Google Developers, “Google Hosted Libraries,” Google Developers: Google Hosted Libraries, Jun. 19, 2020. https://developers.google.com/speed/libraries (accessed Jun. 21, 2020).
  12. [12]
    R. Rabbat, “WebP, a new image format for the Web,” Chromium Blog, Sep. 30, 2010. https://blog.chromium.org/2010/09/webp-new-image-format-for-web.html (accessed Jan. 26, 2020).
  13. [13]
    A. Deveria, “Can I use webP? WebP image format,” Can I use…, Nov. 04, 2019. https://caniuse.com/#search=webp (accessed Jan. 26, 2020).
  14. [14]
    J. Wagner, “Using WebP Images ,” CSS-Tricks, May 02, 2019. https://css-tricks.com/using-webp-images/ (accessed Jan. 26, 2020).
  15. [15]
    P. Venkatesh, “Web Image Formats & Google’s WebP,” Medium, May 14, 2018. https://medium.com/beginners-guide-to-mobile-web-development/web-image-formats-googles-webp-17e2fe5fc53e (accessed Jan. 26, 2020).
  16. [16]
    M. Kearney and P. Bakaus, “Emulate and Test Other Browsers,” Google Developers: Tools for Web Developers, Feb. 12, 2019. https://developers.google.com/web/tools/chrome-devtools/device-mode/testing-other-browsers (accessed Jan. 26, 2020).
  17. [17]
    A. Osmani, S. Little, and R. T, “Automatically lazy-loading offscreen images & iframes for Lite mode users,” Chromium Blog, Oct. 24, 2019. https://blog.chromium.org/2019/10/automatically-lazy-loading-offscreen.html (accessed Jan. 26, 2020).
  18. [18]
    A. Farkas, “lazysizes,” GitHub, Inc., Dec. 18, 2019. https://github.com/aFarkas/lazysizes/tree/master (accessed Jan. 26, 2019).
  19. [19]
    A. Suryadi, “Lazy Load Image And Embed Responsive Youtube Video With Javascript LazySize.js,” Kompi Ajaib, Feb. 2017. https://www.kompiajaib.com/2017/02/lazy-load-image-and-embed-responsive.html (accessed Jan. 26, 2020).
  20. [20]
    V. R. Panambur, “Pros and cons of progress indicator as a scroll bar,” Medium: UX Collective, Oct. 25, 2018. https://uxdesign.cc/pros-and-cons-of-progress-indicator-as-a-scroll-bar-345f19967cb6 (accessed Jan. 27, 2020).
  21. [21]
    C. Coyier, “How Do You Remove Unused CSS From a Site?,” CSS-Tricks, Nov. 29, 2019. https://css-tricks.com/how-do-you-remove-unused-css-from-a-site/ (accessed Jan. 27, 2020).
  22. [22]
    A. Feiglstorfer, “The answer of How to defer load css files (for google speed insights),” Stack Overflow, Jun. 18, 2017. https://stackoverflow.com/questions/44589462/how-to-defer-load-css-files-for-google-speed-insights– (accessed Jan. 27, 2020).
  23. [23]
    Filament Group, “loadCSS,” GitHub, Inc., Jul. 30, 2019. https://github.com/filamentgroup/loadCSS (accessed Jan. 27, 2020).
  24. [24]
    M. Mihajlija, “Establish network connections early to improve perceived page speed,” web.dev, Jul. 30, 2019. https://web.dev/preconnect-and-dns-prefetch/ (accessed May 26, 2020).
  25. [25]
    I. Hindorean, “Understanding Browser Networking and Optimizing Requests for HTTP/1.1 and HTTP/2,” Medium: Better Programming, Jul. 21, 2019. https://medium.com/better-programming/understanding-browser-networking-and-how-to-optimize-the-requests-for-http-1-1-and-http-2-f6371f0af650 (accessed May 26, 2020).
  26. [26]
    W3C, “Resource Hints,” W3C Working Draft, Jul. 02, 2019. https://www.w3.org/TR/resource-hints/ (accessed May 26, 2020).
  27. [27]
    J. Gieryluk, “Answer on ‘preconnect vs dns-prefetch resource hints,’” Stack Overflow, Jun. 27, 2018. https://stackoverflow.com/questions/47273743/preconnect-vs-dns-prefetch-resource-hints (accessed May 26, 2020).
  28. [28]
    D. Aleksandersen, “What to <link rel=dns-prefetch> and when to use preconnect,” Ctrl Blog, Nov. 20, 2019. https://www.ctrl.blog/entry/dns-prefetch-preconnect.html (accessed May 26, 2020).
  29. [29]
    Bungfrangki, “2 Cara Memasang Lazy Load Iklan Adsense,” bungfrangki, Jul. 01, 2019. https://www.bungfrangki.com/2019/07/2-cara-memasang-lazy-load-iklan-adsense.html (accessed Jan. 27, 2020).
  30. [30]
    E. Engi, “The Answer of Load Google Ads after entire page has loaded,” Stack Overflow, Apr. 19, 2016. https://stackoverflow.com/questions/25877461/load-google-ads-after-entire-page-has-loaded (accessed Jan. 27, 2020).
  31. [31]
    WebNots, “6 Ways to Improve the Page Speed of AdSense Site,” WebNots Web Consulting Services, Mar. 25, 2019. https://www.webnots.com/adsense-vs-page-speed-an-irony/ (accessed Jan. 28, 2020).
  32. [32]
    Google, “Set up Auto ads on your site,” Adsense Help, Jan. 01, 2020. https://support.google.com/adsense/answer/9261307?hl=en (accessed Jan. 28, 2020).
  33. [33]
    W3Schools, “The HTML DOM Element Object,” W3Schools, Jan. 08, 2020. https://www.w3schools.com/jsref/dom_obj_all.asp (accessed Jan. 28, 2020).
  34. [34]
    web.dev, “Avoid an excessive DOM size,” web.dev, Oct. 04, 2019. https://web.dev/dom-size/?utm_source=lighthouse&utm_medium=unknown (accessed Jan. 28, 2020).
  35. [35]
    C. Newcomer, “The 13 Best WordPress Comment Plugins to Optimize Engagement (2020),” WP Buffs, Dec. 09, 2019. https://wpbuffs.com/best-comment-plugin-for-wordpress/ (accessed Jan. 28, 2020).

Cover image from pxhere by Mohamed Hassan

Written by Philip F. E. Adipraja

Philip is a Computer Science and Information Engineering student at National Central University, Taiwan. His fields of interest are software engineering, modeling & simulation, intelligent transport system, and smart manufacturing.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.