Optimizing page loads for Giscus comments
A few months ago, I removed Disqus comments from this blog, and replaced it with Giscus, which uses Github discussions for blog comments. When I checked the pagespeed scores of this site recently, I was surprised to see the relatively low scores.
The score was 78 on desktop and 88 on mobile. For a blog this lightweight, I’d have thought the scores would be in the 90s. Turns out that the Giscus JS snippet was adding about 330ms of blocking time to the page load.
Replacing the script
The script below is what you get
when you set up Giscus.
With the data-loading="lazy"
attribute,
it actually does a great job
of not loading things until you scroll down,
but even loading the script has a cost.
<script src="https://giscus.app/client.js"
data-repo="[ENTER REPO HERE]"
data-repo-id="[ENTER REPO ID HERE]"
data-category="[ENTER CATEGORY NAME HERE]"
data-category-id="[ENTER CATEGORY ID HERE]"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="0"
data-emit-metadata="0"
data-input-position="top"
data-theme="dark"
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>
This can be replaced by an inline snippet that waits for a bit before attaching this script tag to the DOM. First let’s write a function that adds the script tag to the page:
<!-- This is where the comments will appear. -->
<div id="comments"></div>
<script>
function loadGiscusComments() {
var script = document.createElement('script');
script.src = "https://giscus.app/client.js";
script.async = true;
script.crossOrigin = "anonymous";
script.setAttribute("data-repo", "nithinbekal/nithinbekal.github.io");
script.setAttribute("data-repo-id", "MDEwOlJlcG9zaXRvcnkxODgzMjgxNg==");
script.setAttribute("data-category", "Comments");
script.setAttribute("data-category-id", "DIC_kwDOAR9dsM4CfG1P");
script.setAttribute("data-mapping", "pathname");
script.setAttribute("data-strict", "1");
script.setAttribute("data-reactions-enabled", "0");
script.setAttribute("data-emit-metadata", "0");
script.setAttribute("data-input-position", "top");
script.setAttribute("data-theme", "transparent_dark");
script.setAttribute("data-lang", "en");
script.setAttribute("data-loading", "lazy");
document.getElementById("comments").appendChild(script);
}
</script>
Next, we’ll trigger this function either when the user scrolls the page, or after 5 seconds after page load.
// function loadGiscusComments() { ... }
var scriptLoaded = false;
function loadCommentScriptOnce() {
if (!scriptLoaded) {
loadGiscusComments();
scriptLoaded = true;
}
}
setTimeout(loadCommentScriptOnce, 5000);
window.addEventListener("scroll", loadCommentScriptOnce);
See the commit here: Load Giscus after 5s or on scroll
Improvements
Once I put in the new snippet, the pagespeed scores improved significantly, including a 100 pagespeed score for desktop.
Lighthouse scores
- Desktop: 100 (previously 78)
- Mobile: 97 (previously 88)
Total blocking time
- Desktop: 20ms (previously 530ms)
- Mobile: 180ms (previously 460ms)
Links
I came across More tips for using giscus by Bryce Wray, which takes another approach to this, by only loading the comments when someone clicks a “Show comments” button.
Another idea there was to
use preconnect
and dns-prefetch
resource hints.
I might look into that at some point,
but for now I’m happy with how fast the page load is.