Core Web Vitals Niche Tip: Live Chat Script

I’m currently in the privileged position of building up a site for a client from scratch as part of a wider rebrand. Despite the urgency to boil the ocean before the end of the mighty 2020, this has allowed me more of a voice than usual from the ground up with devs, creatives, product teams, CMOs and so on. No pressure then.

As a result, this has led to some interesting findings thanks to the rabbit hole of experiments I’ve had the luxury to perform. One of these is with a view to improving site speed performance in various staging environments, and I thought I might document some of these with the vain hope they may help someone at some point. First up is live chat apps.

talk talk talk
Fans of either the Psychedelic Furs or live chat apps: talk to me.

Disclaimer: Some of these may be familiar and well-documented by others and some of them may be totally unrelatable. I’m hoping somewhere in the middle there’s something useful.


Core Web Vitals: A 2021 To Remember

Before we delve in…

When I think of the Core Web Vitals potential apocalypse in May 2021, the first thing that comes to mind in terms of the firing line is certain news and publisher sites and their heavy use of JS and third-party APIs that just make their performance dreadful. Some of these (obviously) deserve to be punished without mercy. Whether the potential Core Web Vitals hit has a hugely adverse effect on their huge pie of organic performance as a whole will be interesting to see.

But alas, I’m not tackling a site in the news and publishing sector. Experience suggests however that quite a lot of ecommerce sites out there with tendencies to rely on heavy use of React, 3rd party CRM scripts and general code bloat etc may be at serious risk.


Stop waffling. What was it about live chat then?

Yes, that was quite a long intro (sorry). But if I am actually going to commit and make this an attempt at a miniseries then perhaps it was necessary. Down to it then.

Obviously, there’s plenty you could and should be doing to improve your Core Web Vitals score on certain pages. The tip I’m going to share concerns 3rd party live chat pop-ups, something which can be ubiquitous to ecommerce sites and the favoured child of many a CRM manager out there.

Live chat pop-ups are of course crucial for gathering customer data, gathering leads, converting clients. But guess what? Many, by default, fire up as part of first paint and will skew your LCP time which in turn may do this to your overall PageSpeed Insights score:

Mobile on the left, desktop on the right (duh).

If you’re using WordPress, Google’s PageSpeed test/Lighthouse report (these are only two of at least 55 page speed tools you should be consulting) may advise you to install certain plugins to fix certain performance issues such as JS deferring and next-gen image serving in order to improve your Core Web Vitals score. I highly recommend you tell all your contemporaries and competitors to completely go to town on this method and then leave it at that.

With third-party scripts like live chat tools however, (in this case study HubSpot) consider the approach of codes snippets to defer the loading of your live chat tool so it only fires up when a user engages with it and not upon overall initial page load.

This can bring savings across the board especially if you’re deploying a live chat script on the majority of your site as many ecommerce brands may be tempted to.

I’m reliably informed that there is an option to toggle this easily within the HubSpot live chat app. If not, the snippet of code to achieve this should look something like this:

//Prevent chat from loading immediately load only if chat is not in progress or #hs-chat-open is not in the url
if (sessionStorage.getItem("chatInProgress") !== "true" && window.location.hash !== "#hs-chat-open") {
    window.hsConversationsSettings = { loadImmediately: false };
}

And is complemented by the below code that ensures the live chat app is fired up upon user interaction:

if (window.HubSpotConversations) {
            hubspotChatReady();
        } else {
            window.hsConversationsOnReady = [hubspotChatReady];
        }
        function hubspotChatReady() {
            //Proceed to immediately load Live Chat while conversation is persisting
            window.HubSpotConversations.addEventListener("conversationStarted", function () {
                sessionStorage.setItem("chatInProgress", "true");
            });
            window.HubSpotConversations.addEventListener("conversationClosed", function () {
                sessionStorage.removeItem("chatInProgress");
            });
            //Fake Hubspot Live chat button to launch real live chat only when user clicks
            //Ignore if Live Chat is already loaded
            if (window.HubSpotConversations.widget.status().loaded === false) {
                var $liveChat = document.getElementById("activate-chat");
                $liveChat.style.display = "block";
                $liveChat.addEventListener("click", function (event) {
                    event.preventDefault();
                    $liveChat.classList.add("loading");
                    //Chat window is open when the iframe is loaded in the dom (Hubspot doesn't give a callback for the chat window opening)
                    var observer = new MutationObserver(function (mutationList, observer) {
                        mutationList.forEach(function (m) {
                            m.addedNodes.forEach(function (n) {
                                if (n.id === "hubspot-messages-iframe-container") {
                                    n.querySelector('iframe').addEventListener('load', function () {
                                        $liveChat.classList.remove("loading");
                                        window.HubSpotConversations.widget.open();
                                        observer.disconnect();
                                    });
                                }
                            });
                        });
                    });
                    observer.observe(document.body, { childList: true, attributes: false, subtree: false });
                    window.HubSpotConversations.widget.load({ widgetOpen: true });
                })
            }
        }

NB: Not being a developer, I didn’t come up with the code solution myself. It was in part assisted by trawling across various HubSpot Community forums in order to mangle together a fix. There’s plenty of contributions out there, so fill ya boots and see what works. I would also suggest you play around with this and don’t do a direct copy and paste to ensure it doesn’t completely break your live chat app integration.

And of course, here’s the inevitable self-justification-for-this-blog-post PageSpeed Insight score after the above was implemented successfully:

Mobile still on the left, desktop still on right (still duh).

I hope that helps.