On Your Marks, Get Set, Wait https://repc.co/sfn8k

tagged under ,
reading time 11 mins

I’ve modified the JavaScript for this section of my site over time, but have reflected the changes in the code snippets below.

Since the last re-design of my website, I decided to make the switch to Disqus for my commenting system. This comes with a couple of disadvantages but also with a few advantages.

Disqus © 2012.

In this article I’m going to run through how I manage my comments section from a front-end development perspective, with respect to user experience, performance, and accessibility.

The Cons of Disqus #cons

The Pros of Disqus #pros

The Weigh In #the-weigh-in

First, let’s look at some statistics for loading Disqus comments on page load:

By and large, this isn’t a massive hit. But we can almost always make things faster. I think it comes down what content is important—most people don’t comment on my articles, which begs the question: do most people care about the comments? That’s a difficult question to answer, but I think the point to drive home is that most people seem not to need the comments section—they’re here to read the articles. Maybe that will change over time, but with a mobile first approach, it’s important to consider what constraints mobile users could be under; namely, poor Internet connection speed and low processing power. The number of users browsing on mobile phones and tablets has only escalated in recent years, and we should be able to cater to their needs in ways other than just building responsively.

You shouldn’t impede your users access to your content by requiring them to download things that do not support it. Related articles, comments etc, these are secondary to the content itself, so if the user wants to see that they’ll be happy to exchange a single click over more DB queries at run time, or additional HTTP requests and JavaScript interpretation. Essentially, build it progressively enhanced.

Justin Avery of Responsive Web Design

So what can we do to reduce the page weight and load time for a majority of users? We can conditionally load comments as and when a user wants them.

At My Signal, Unleash Hell #at-my-signal

Let’s decide what the conditions are for loading the comments:

  1. The user has finished reading the article, gets to the bottom of the page, and wants to read the comments
  2. The user navigates to the page from a link that directs them to the comments (with #comments appended to the URL)
  3. The user clicks a link to the comments section from within the article itself (also by #comments being appended to the URL)

Let’s dive into some code. Here’s how I was loading Disqus non-conditionally:

(function(d) {
    var typekitTimeout = 5000;
    if( window.sessionStorage ) {
        if( sessionStorage.getItem('useTypekit') === 'false' ) {
            typekitTimeout = 0;
        }
    }
    var config = {
        kitId: 'bbn1puz',
        scriptTimeout: typekitTimeout
    },
    h = d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+"wf-inactive";if(window.sessionStorage){sessionStorage.setItem("useTypekit","false")}},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+="wf-loading";tk.src='//use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
})(document);

I didn’t want to reinvent the wheel, so I followed in the footsteps of others who have done the same thing. First I wanted to create an action for the user to perform if they reached the bottom of an article and want to dip into the comments, and did so with a button.

<button class="button--show-comments" id="js-show-comments" role="button" aria-pressed="false" disabled>
    <svg class="icon  icon--feather"><use xlink:href="#svg--feather" /></svg>
    <span class="disqus-comment-count" data-disqus-url="http://foo.bar">Leave a Comment</span>
</button>

And let’s create some associated JavaScript to create and hook onto our button and perform two actions: remove the button and load Disqus.

var commentsButton  = document.querySelector('#js-show-comments');

commentsButton.disabled = false;

commentsButton.addEventListener('click', function() {
    showComments();
});

function showComments() {
    commentsButton.parentNode.removeChild(commentsButton);
    commentsButton.removeEventListener('click', function(){});

    (function() {
        var dsq = document.createElement('script');
            dsq.type = 'text/javascript';
            dsq.async = true;
            dsq.src = '//' + DISQUS_SHORTNAME + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
}

What we’re doing here is:

  1. Assigning our button to a variable
  2. Adding an click event listener to our button (which fortunately also works via keyboard commands)
  3. When the button is clicked, remove the button and load in our comments

Everything’s looking sweet so far, so let’s tackle the 2nd and 3rd conditions from above: watching for a hash change in the URL (pointing to #comment) or catching it when the page is loaded.

var commentsHash = ['#comment', '#disqus_thread'];

window.addEventListener('load', function() {
    updateFromHash();
});

window.addEventListener('hashchange', function() {
    updateFromHash();
});

function updateFromHash() {
    commentsHash.forEach( function(hash) {
        if( window.location.hash.indexOf(hash) === 0 ) {
            showComments();
        }
    });
}

What we’re doing here is:

  1. Assign our hash value to a variable (because why not?)
  2. If the URL already contains our desired hash on page load, run the showComments() command
  3. If the hash changes in the URL after the page has loaded, and it matches our desired value, run the showComments() command

If you remember, the showComments() function removes the button we created before—we want to do the same thing if #comment is in the URL and we’re loading Disqus, as we don’t want or need users to be able to load comments twice; in fact, that would be completely the opposite of what we’re trying to achieve here!


Almost there! Let’s create a failsafe—if our button no longer exists when the showComments() function is run, that means we’ve already loaded the comments, so we shouldn’t do it again.

function showComments() {
    if( commentsButton !== null ) {
        commentsButton.parentNode.removeChild(commentsButton);
        commentsButton.removeEventListening('click', function(){});

        (function() {
            var dsq = document.createElement('script');
                dsq.type = 'text/javascript';
                dsq.async = true;
                dsq.src = '//' + DISQUS_SHORTNAME + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.  getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    }
}

The Whole Nine Yards #the-whole-nine-yards

Here’s the entire snippet of code for my comments section:

<button class="button--show-comments" id="js-show-comments" role="button" aria-pressed="false" disabled>
    <svg class="icon  icon--feather"><use xlink:href="#svg--feather" /></svg>
    <span class="disqus-comment-count" data-disqus-url="http://foo.bar">Leave a Comment</span>
</button>
<section id="comments" class="clear  comments">
    <div id="disqus_thread"></div>
    <noscript>Please enable JavaScript to view comments.</noscript>
</section>
var DISQUS_SHORTNAME = 'chrisburnell';

We’ve met all the conditions we set when we embarked upon this task:

  1. Create a button to load the comments
  2. Load the comments if the page was navigated to with the #comment hash
  3. Load the comments if the user clicks an anchor to jump to #comment section

As we saw in the statistics of Disqus’ impact, these aren’t massive savings, but they’ll certainly help out some of my users whom I know are browsing on slow connections and slow mobile phones.


We still have a small thorn when it comes to users without JavaScript enabled. Of course, the noscript tag will display a message, Please enable JavaScript to view comments, but there’s no way for those users to view the comments. On the other hand, Disqus have discussion pages for each of your articles, but the URL isn’t predictable enough to print this URL with my CMS (Jekyll) dynamically; furthermore, these pages don’t work without JavaScript enabled anyway.

A List Apart has a pretty nice solution to this in the same vein as Disqus, but it works without JavaScript enabled, for example: this comments page. Maybe if Disqus was able to give a similar URL back in the case where JavaScript is disabled, but as it’s an external service, this doesn’t seem possible without JavaScript. https://disqus.com/comments/?url=https://chrisburnell.com/article/a-slice-of-heaven is a possible solution to a minor problem—let’s hope Disqus implements something like this soon.


Big thanks to Ben Walters, a JavaScript wizard and close friend of mine, for helping me achieve this solution.

Let me know, as always, down below (treat that link as a proof of concept) if you have any suggestions for improvements to my code or other ideas on the matter. ’Til next time!

Latest Articles

All Articles