Facebook chat plugin "kills" Pagespeed to 33
Asked Answered
N

3

9

I have added the Facebook chat plugin through this code generated from facebook.com

<!-- Load Facebook SDK for JavaScript -->
<div id="fb-root"></div>
<script>(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/en_US/sdk/xfbml.customerchat.js';
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

<!-- Your customer chat code -->
<div class="fb-customerchat"
  attribution=setup_tool
  page_id="124030157608968">
</div>`

However I run a Pagespeed test in Google Chrome and the results are disaster.

Any suggestions how to solve this problem?

Thank you very much!

enter image description here

Nonah answered 27/11, 2018 at 12:54 Comment(1)
There is little you can do about this, since these are all assets loaded by the plugin, and not under your control. – Sestertium
P
7

Same issue. No matter if you initialize it in an async manner or not, it literally kills the Page speed index of your website!

Here's an approach I did in order to fully go around this disaster.

I placed a fake πŸ™„ Messanger button at the bottom right of the page:

<svg id="fb-messanger-fake-button" width="60px" height="60px" viewBox="0 0 60 60" cursor="pointer">
    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g>
        <circle fill="#00B2FF" cx="30" cy="30" r="30"></circle><svg x="10" y="10">
            <g transform="translate(0.000000, -10.000000)" fill="#FFFFFF">
            <g id="logo" transform="translate(0.000000, 10.000000)">
                <path
                d="M20,0 C31.2666,0 40,8.2528 40,19.4 C40,30.5472 31.2666,38.8 20,38.8 C17.9763,38.8 16.0348,38.5327 14.2106,38.0311 C13.856,37.9335 13.4789,37.9612 13.1424,38.1098 L9.1727,39.8621 C8.1343,40.3205 6.9621,39.5819 6.9273,38.4474 L6.8184,34.8894 C6.805,34.4513 6.6078,34.0414 6.2811,33.7492 C2.3896,30.2691 0,25.2307 0,19.4 C0,8.2528 8.7334,0 20,0 Z M7.99009,25.07344 C7.42629,25.96794 8.52579,26.97594 9.36809,26.33674 L15.67879,21.54734 C16.10569,21.22334 16.69559,21.22164 17.12429,21.54314 L21.79709,25.04774 C23.19919,26.09944 25.20039,25.73014 26.13499,24.24744 L32.00999,14.92654 C32.57369,14.03204 31.47419,13.02404 30.63189,13.66324 L24.32119,18.45264 C23.89429,18.77664 23.30439,18.77834 22.87569,18.45674 L18.20299,14.95224 C16.80079,13.90064 14.79959,14.26984 13.86509,15.75264 L7.99009,25.07344 Z">
                </path>
            </g>
            </g>
        </svg>
        </g>
    </g>
</svg>

... aaaand I positioned it with CSS on the bottom right corner, EXACTLY where the real Messanger button will appear (based on your configuration):

#fb-messanger-fake-button {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 100;
    transition: opacity 0.3s;
}

Using jQuery (in my case) or just plain JavaScript (if you want), implement logic that injects the Facebook SDK and initiates the Messanger plugin ONLY when the user clicks on our fake Messanger button:

// Facebook SDK for JavaScript inject code
function injectFbSdkAsync(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/en_US/sdk/xfbml.customerchat.js';
    fjs.parentNode.insertBefore(js, fjs);
};

$(function() {
    const $fbMessangerFakeButton = $('#fb-messanger-fake-button');
    $fbMessangerFakeButton.on('click', function(){
        // Fades out the fake button a bit, to indicate "loading"
        $fbMessangerFakeButton.css({ opacity: 0.4 });
        // Inject the Facebook SDK in async manner:
        injectFbSdkAsync(document, 'script', 'facebook-jssdk');

        // Callback on Facebook SDK init, that fires up the Messanger plugin
        window.fbAsyncInit = function() {
            FB.init({ xfbml: true, version: 'v8.0' });

            // Callback when Facebook SDK finish up with rendering
            FB.Event.subscribe('xfbml.render', function(){
                // Immediately toggle opening the Facebook Messanger,
                // as if the user clicked the real Messanger button.
                FB.CustomerChat.show(true);

                // Hide the fake button, so that only the real one remains!
                $fbMessangerFakeButton.css({ display: 'none' });
            });
        };
    });
});

And that's it! Your page speed index is back to normal.

Previse answered 25/10, 2020 at 18:28 Comment(0)
G
1

I like Kaloyan's approach very much. Thank you! It is extremely useful and helping in website performance, which becomes evidently better.

I've improved the fake button with a little spinner inside, as loading indicator - just for better UX.

Also wrapped SVG with button tag (for better a11y, I believe), and don't use jQuery anymore.

Messenger Fake Button

Full code, to hook at the end of the page (in footer maybe).

<button id="fb-messenger-fake-button">
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 1024 1024" aria-hidden="true">
    <circle fill="#00B2FF" style="fill: var(--msgr-color, #00B2FF)" cx="512" cy="512" r="512"/>
    <g id="spinner" fill="#fff"><circle cx="512" cy="239" r="47"/><circle cx="375" cy="275" r="47" fill-opacity="0.9"/><circle cx="275" cy="375" r="47" fill-opacity="0.8"/><circle cx="239" cy="512" r="47" fill-opacity="0.7"/><circle cx="275" cy="649" r="47" fill-opacity="0.6"/><circle cx="375" cy="749" r="47" fill-opacity="0.5"/><circle cx="512" cy="785" r="47" fill-opacity="0.4"/><circle cx="649" cy="749" r="47" fill-opacity="0.3"/><circle cx="749" cy="649" r="47" fill-opacity="0.2"/><circle cx="785" cy="512" r="47" fill-opacity="0.1"/></g>
    <path id="logo" fill="#fff" d="M512 171c192 0 341 141 341 331S704 833 512 833c-35 0-68-5-99-13-6-2-12-1-18 1l-68 30c-17 8-37-5-38-24l-2-61c0-7-4-14-9-19a324 324 0 01-107-245c0-190 149-331 341-331zM307 599c-10 15 9 32 24 21l107-82c8-5 18-5 25 0l80 60c24 18 58 12 74-14l100-159c10-15-9-32-24-21l-107 82c-8 5-18 5-25 0l-80-60a51 51 0 00-74 13L307 599z"/>
</svg><span class="screen-reader-text">Enable chat via Messenger</span>
</button>

<!-- Messenger Chat plugin Code -->
<div id="fb-root"></div>
<!-- Your Chat Plugin code -->
<!-- Put the ID of your page on Facebook, at least -->
<div class="fb-customerchat"
 attribution=setup_tool
 page_id="000000000000000"
 theme_color="#00B2FF"
 logged_in_greeting="Hi! How can I help you?"
 logged_out_greeting="Hi! How can I help you?">
</div>

<script>
// Facebook SDK for JavaScript inject code
// Change language part to yours, e.g.: en_US > pl_PL
function injectFbSdkAsync(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/en_US/sdk/xfbml.customerchat.js";
  fjs.parentNode.insertBefore(js, fjs);
}

var fbMessengerFakeButton = document.getElementById('fb-messenger-fake-button');
fbMessengerFakeButton.addEventListener('click', function() {
    
  // Once #fb-messenger-fake-button is clicked triggers animated spinner inside it 
  // See CSS, and SVG structure inside the button
  this.classList.add('active');
    
  // Inject the Facebook SDK in async manner:
  injectFbSdkAsync(document, "script", "facebook-jssdk");

  // Callback on Facebook SDK init, that fires up the Messenger plugin
  window.fbAsyncInit = function () {
    FB.init({ xfbml: true, version: "v10.0" });

    // Callback when Facebook SDK finish up with rendering
    FB.Event.subscribe("xfbml.render", function () {
      // Opening the Facebook Messenger
      FB.CustomerChat.show(true);
            
      // Hide the fake button, so that only the real one remains!
      fbMessengerFakeButton.style.display = 'none';
    });
  };
});
</script>

CSS

#fb-messenger-fake-button {
    position: fixed;
    z-index: 100;
    bottom: 24px;
    right: 24px;
    padding: 0 !important;
    border-radius: 50%;
    /* you may use a color of your theme */
    --msgr-color: transparent;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    cursor: pointer;
    transition: all 0.3s;
}
#fb-messenger-fake-button svg {
    display: block;
}
#fb-messenger-fake-button.active #logo {
    opacity: 0;
}
#fb-messenger-fake-button.active #spinner {
    animation: spin 3s linear infinite;
    transform-origin: center;
}
@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

Where to setup Messenger chat at Facebook

Go to your page on Facebook: Settings β†’ Messaging β†’ Add Messenger to your website β†’ Get Started

There, most of all, you need to put your website domain.

Gonophore answered 16/4, 2021 at 11:42 Comment(0)
O
0
  1. Put the whole code on the very bottom of the source code
  2. Save https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js locally, implement it from there with defer.
Oyster answered 30/11, 2018 at 14:21 Comment(3)
Can you please elaborate what do you mean by saying: "implement it from there"? - I understood to copy the script locall, then what should I place in 'js.src=' ? – Compelling
You save this file https://connect.facebook.net/en_US/sdk/xfbml.customerchat.js locally. Than you change its url in the code snippet to https://your-domain.com/xfbml.customerchat.js or where you saved it. – Oyster
I tried this and it doesn't boost up the page speed much. The main reason for that reduction on page speed is mostly made by the PHP file and that package of a lot of js files triggered by that js code, not the size of js itself. Also, it looks like google's page insight is ignoring defer and async as they didn't make any change on my page score. – Flashing

© 2022 - 2024 β€” McMap. All rights reserved.