How to best defer scripts to be excluded from PageSpeed Insights?

2.4k views Asked by At

We use Zopim on our website. Unfortunately, because of this we are significantly punished on PageSpeed Insights.

  • Without Zopim: 86/100
  • With Zopim: 66/100

Zopim seems to be aware of the issue, and promises to further optimize their widget, but we haven't seen much progress yet.

The code to add Zopim is as follows:

<script type="text/javascript">
  window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=
  d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set.
  _.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8");
  $.src="https://v2.zopim.com/?2dAdkKRoqdi9hHHrfr302XabQaK8DN7f";z.t=+new Date;$.
  type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script");
</script>

I have been playing around with different ways of deferring the execution of the script (defer and async), but have been unsuccessful in improving our PageSpeed Insights score (without removing Zopim altogether).

I came to this article but my naive attempt (replace "defer.js" with "https://v2.zopim.com/?2dAdkKRoqdi9hHHrfr302XabQaK8DN7f") did not have the desired effect and Zopim is still counted by PageSpeed.

My question:

  • what is the best way to defer non-critical scripts to ensure that PageSpeed Insights do not count the script as part of its score?
  • how to apply that to the Zopim script?
4

There are 4 answers

2
Marco Romano On

In this article is write the best solution: here

"We changed the logic behind loading this script. The script loading starts when a user performs the first action. As an action we consider: scroll, mouse click, mouse move, touch on screen or keydown."

Work so nice!

<script>
            document.addEventListener('scroll', zopimlaunch);
            document.addEventListener('mousedown', zopimlaunch);
            document.addEventListener('mousemove', zopimlaunch);
            document.addEventListener('touchstart', zopimlaunch);
            document.addEventListener('scroll', zopimlaunch);
            document.addEventListener('keydown', zopimlaunch);

            function zopimlaunch () {
                window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set._.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute('charset','utf-8');
                $.src='//v2.zopim.com/?yourid';z.t=+new Date;$.type='text/javascript';e.parentNode.insertBefore($,e)})(document,'script');

                document.removeEventListener('scroll', zopimlaunch);
                document.removeEventListener('mousedown', zopimlaunch);
                document.removeEventListener('mousemove', zopimlaunch);
                document.removeEventListener('touchstart', zopimlaunch);
                document.removeEventListener('scroll', zopimlaunch);
                document.removeEventListener('keydown', zopimlaunch);
            }

</script>

0
David Motilla On

You can do it by adding $.setAttribute("defer",null); at the end of the third line of javascript, so that it is as follows:

<script type="text/javascript">
  window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=
  d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set.
  _.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8");$.setAttribute("defer",null);
  $.src="https://v2.zopim.com/?2dAdkKRoqdi9hHHrfr302XabQaK8DN7f";z.t=+new Date;$.
  type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script");
</script>
0
user2129024 On

Yes,zopim are not in my good books so I have also been messing around trying to fix their code. This is how I have deferred the zopim script.

<script type="text/javascript">  
  function do_zopim() {
    jQuery(document).on("mousemove.zopim_defer scroll.zopim_defer", function(e) {
      window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=
      d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set.
      _.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8");
      $.src="https://v2.zopim.com/?anonymous";z.t=+new Date;$.
      type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script");
      jQuery(document).off("mousemove.zopim_defer scroll.zopim_defer");
    });
  }
</script>

<body onload="do_zopim();">
0
Steven Sproat On

I've changed my site so that Zopim gets loaded after the page itself has loaded, as opposed to being an integral part of that initial page load. Place this just before your </body>:

    <script>
    window.addEventListener("load", function () {
        window.$zopim || (function (d, s) {
            var z = $zopim = function (c) { z._.push(c) },
                $ = z.s = d.createElement(s), e = d.getElementsByTagName(s)[0]; z.set = function (o) {
                    z.set._.push(o);
                }; z._ = []; z.set._ = []; $.async = !0; $.setAttribute('charset', 'utf-8');
            $.src = '//v2.zopim.com/?1ubUmoyGvu8nQlye7YBWC3pLL0lgJDUf'; z.t = +new Date; $.
                type = 'text/javascript'; e.parentNode.insertBefore($, e);
        })(document, 'script');
    })
</script>