Third Party Performance

Use the noscript version only.

Not all products have a noscript version of their code, but for those that do, this is a great option when performance is critical.

This is the default implementation code from Piwik Pro analytics.

<script>
  (function (window, document, dataLayerName, id) {
    (window[dataLayerName] = window[dataLayerName] || []),
      window[dataLayerName].push({
        start: new Date().getTime(),
        event: "stg.start",
      });
    var scripts = document.getElementsByTagName("script")[0],
      tags = document.createElement("script");
    function stgCreateCookie(a, b, c) {
      var d = "";
      if (c) {
        var e = new Date();
        e.setTime(e.getTime() + 24 * c * 60 * 60 * 1e3),
          (d = ";expires=" + e.toUTCString());
      }
      document.cookie = a + "=" + b + d + ";path=/";
    }
    var isStgDebug =
      (window.location.href.match("stg_debug") ||
        document.cookie.match("stg_debug")) &&
      !window.location.href.match("stg_disable_debug");
    stgCreateCookie("stg_debug", isStgDebug ? 1 : "", isStgDebug ? 14 : -1);
    var qP = [];
    dataLayerName !== "dataLayer" &&
      qP.push("data_layer_name=" + dataLayerName),
      isStgDebug && qP.push("stg_debug");
    var qPString = qP.length > 0 ? "?" + qP.join("&") : "";
    (tags.async = !0),
      (tags.src =
        "https://marketing.containers.piwik.pro/" + id + ".js" + qPString),
      scripts.parentNode.insertBefore(tags, scripts);
    !(function (a, n, i) {
      a[n] = a[n] || {};
      for (var c = 0; c < i.length; c++)
        !(function (i) {
          (a[n][i] = a[n][i] || {}),
            (a[n][i].api =
              a[n][i].api ||
              function () {
                var a = [].slice.call(arguments, 0);
                "string" == typeof a[0] &&
                  window[dataLayerName].push({
                    event: n + "." + i + ":" + a[0],
                    parameters: [].slice.call(arguments, 1),
                  });
              });
        })(i[c]);
    })(window, "ppms", ["tm", "cm"]);
  })(window, document, "dataLayer", "ACCOUNT_ID_PARAMETER");
</script>
<noscript
  ><iframe
    src="https://marketing.containers.piwik.pro/ACCOUNT_ID_PARAMETER/noscript.html"
    height="0"
    width="0"
    style="display:none;visibility:hidden"
  ></iframe
></noscript>

If you just need bare-bones tracking, you can just use what is inside the noscript portion of the code. Taking the example above, you're left with this:

<iframe
  src="https://marketing.containers.piwik.pro/ACCOUNT_ID_PARAMETER/noscript.html"
  height="0"
  width="0"
  style="display:none;visibility:hidden"
></iframe>

Use requestIdleCallback or setTimeout

Below is the default implementation code for HotJar. This script is async. That is, it won't block the initial render, but it will execute as soon as it is downloaded, so it could pause HTML parsing if it's loaded quick enough. The script is inserted with the line that says a.appendChild(r);.

<script>
  (function (h, o, t, j, a, r) {
    h.hj =
      h.hj ||
      function () {
        (h.hj.q = h.hj.q || []).push(arguments);
      };
    h._hjSettings = { hjid: 123456, hjsv: 6 };
    a = o.getElementsByTagName("head")[0];
    r = o.createElement("script");
    r.async = 1;
    r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
    a.appendChild(r);
  })(window, document, "https://static.hotjar.com/c/hotjar-", ".js?sv=");
</script>

If we wrap the script insertion part with requestIdleCallback, that will delay the script insertion. This will make the appendChild operation lower priority. It's considered a background task, and the browsers will execute it thinks it has time to do so.

<script>
  (function (h, o, t, j, a, r) {
    h.hj =
      h.hj ||
      function () {
        (h.hj.q = h.hj.q || []).push(arguments);
      };
    h._hjSettings = { hjid: 123456, hjsv: 6 };
    a = o.getElementsByTagName("head")[0];
    r = o.createElement("script");
    r.async = 1;
    r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
    // here is where we wrap it
    window.requestIdleCallback(() => {
      a.appendChild(r);
    });
    // end wrap
  })(window, document, "https://static.hotjar.com/c/hotjar-", ".js?sv=");
</script>