'Facebook Customer Chat slowing down your website? Found solution to trick Google PageSpeed Insights
Today i encountered issue with Facebook SDK. Facebook Customer Chat have drastically lowered my Google PageSpeed Insights score by over a 40 points... I have't found any answers on stack, so i came up with a solution i decided to share with you.
It's not the prettiest one, and it's not solving slow Facebook SDK issue. Just trick's Google PageSpeed Insights score!
My solution is to place section into setTimeout(), and wait (in my case) for 5secounds. This, gives time google speed checker to measure response time, and give score.
Hope i helped someone!
const facebookChat = () => {
window.fbAsyncInit = function() {
FB.init({
xfbml : true,
version : 'v9.0'
});
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = 'https://connect.facebook.net/pl_PL/sdk/xfbml.customerchat.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
setTimeout(facebookChat, 5000);
Solution 1:[1]
Loading on delay is no longer a good idea in most circumstances
Adding a script after a delay is not anything new and I have expressed concerns / problems with a very similar solution of using a delay on the script before.
Now since my first answer I listed there things have changed a lot and I would no longer advise using setTimeout
for delaying scripts due to massive variability in connection speeds in the real world.
Google Page Speed Insights is much more relevant now due to the introduction of Web Vitals, with a huge update to Google Search algorithm being implemented next year around these metrics.
These metrics are measured in the real world, so hacks are not going to cut it anymore.
A better way - loading on intent
As such a much better approach is to load facebook messenger on intent.
By this I mean:
- Add the facebook messenger script as the very last item to download, ensure it has the
async
ordefer
attribute. do not initialise the script - add a custom "facebook messenger" button to your page.
- when a user clicks that button initialise the messenger.
- replace your custom button with the facebook chat button (it should automatically appear so just hide your button).
A lot of the issues with messenger are due to the massive code bloat and high CPU execution time of that code.
If you implement it this way you are not delaying any rendering (due to async
or defer
on the script tag) and you are not having to worry about the overhead of initialising the messenger until the user presses your button.
Advanced way to determine when to include bloated scripts
You need to know the network speed (and CPU speed if possible) and then you can include the facebook script early if the network speed is fast or late if it is slow.
Network Speed
Luckily nowadays we can actually calculate network speed pretty reliably and make a decent guess for CPU speed.
Network speed can be calculated by using a performanceObserver
.
You look at the first 10 requests on a page (using `entryType == "resource"``) and from that we can calculate network latency and download speed.
Then we set some threshold that we think is fast enough to include facebook messenger early or late and act accordingly.
You can also use performance observer to see when all resources are downloaded on the page if you know how many requests the page has and then trigger the facebook script download.
CPU speed
With regards to CPU - if the browser supports it we can gather how many cores a processor has using window.navigator.hardwareConcurrency
, 4 or less we assume it is slower, 5 or more we assume it is faster. It isn't super accurate but it can be a nice addition to the above method for making fine adjustments.
Alternatively for calculating CPU load you could use performanceObserver
again to listen for longtask
items. If there have been no long tasks for X seconds then include the facebook script.
This can be achieved by setting a timer for x seconds and then listening for entryType== "longtask"
and then resetting the timer if a longtask
entry occurs.
This final way of doing it ensures that on a very slow device facebook messenger is not being loaded until the rendering and bootstrapping of the essential page items is complete.
Final Thoughts
In the end it all depends on how important Facebook Messenger (or any third party library) is as to when you load it and how you handle it.
Using the web vitals library to measure Real User Metrics (RUM) is far better for making decisions like this than arbitrarily adding a delay, you may find most of your users do not experience a problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |