Facebook Pixel Is Slowing Down Your Website (And How To Fix It, Securely)
Tags: facebookpixel, contentsecuritypolicy, pagespeedoptimization, pagespeedloading
Published: 2020-07-20 13:37:37

---
title: Facebook Pixel Is Slowing Down Your Website (And How To Fix It, Securely)
published: true
description: Facebook Pixel is slowing down your website. Learn how you can use this amazing analytics tool without hurting your page speed and keeping your site secure.
tags: facebookpixel, contentsecuritypolicy, pagespeedoptimization, pagespeedloading
canonical_url: https://josephpinder.com/blog/facebook-pixel-is-slowing-down-your-website-and-how-to-fix-it-securely
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/g3lba1cjdnpuas6jurfj.jpg
---

Analytical tools are ubiquitous with the modern web. Even the most basic website has at least one of these analytical tools (most, likely Google Analytics) running in the background. Why not Facebook?

In this article, we will find out how Facebook Pixel slows down your website and how to resolve this problem securely.

Facebook Pixel is an analytics tool that helps you:

* track conversions from Facebook ads,
* optimize Facebook Ads,
* build targeted audiences for future ads,
* and remarket to people who have taken some kind of action on your website.

It's a great tool, but it's a tool that might be slowing your website down, costing you leads and money.

## What's the problem?

If you're following [Facebook's instructions on installing Facebook Pixel](https://www.facebook.com/business/help/952192354843755?id=1205376682832142) or getting some, umm... expert advice, you'll most likely be advised to place the Facebook Pixel code in your site's `head` element.

<strong>Don't do this!</strong>

![GT Metrix results before Facebook Pixel fix](https://dev-to-uploads.s3.amazonaws.com/i/qh3ww0vgrv9qji9l9s2c.jpg)
<figcaption>Fig 1.1 — GT Metrix results before Facebook Pixel fix.</figcaption>

Unedited, Facebook's little code snippet can add anywhere from 1.3–1.5 seconds to your page's load time. To make matters worse, the script is loaded, four HTTP requests made and 170KB added to your [page weight](https://whatdoesmysitecost.com/) (or page size) all before your page's First Paint—that's before the first pixel is even visible on the screen.

The entire point of page speed optimization is to reduce page weight and the number of HTTP requests, allowing the most important aspects of your page to load first. [According to Google](https://webmasters.googleblog.com/2010/05/you-and-site-performance-sitting-in.html), <q cite="https://webmasters.googleblog.com/2010/05/you-and-site-performance-sitting-in.html">2 seconds is the threshold for... site acceptability... at Google... under half a second.</q> Considering a truly perfomant website loads in a second or less, do you really want to add Facebook's 1.5s to your site's page load time?

If you're like me and using [GT Metrix](https://gtmetrix.com) to test your page's performance, you will also be presented with some other warnings like <strong>Leverage browser caching</strong>, <strong>Specify a cache validator</strong> and <strong>Add Expires headers</strong>.

So, how can we resolve these issues?

## Google Tag Manager

Over at [8WebDesign](https://www.8webdesign.com.au), a recommended solution was [to use Google Tag Manager](https://www.8webdesign.com.au/website-speed/facebook-pixel-making-website-slower/).

This wasn't a bad attempt. It works in part and with some exceptions.

The first issue is that while Google Tag Manager does indeed reduce page load time, it has no way of dealing with the cache issues listed earlier. You will still see warnings for <strong>Leverage browser caching</strong>, <strong>Specify a cache validator</strong> and <strong>Add Expires headers</strong>.

The second problem and more importantly, unlike Google Analytics which is native to Google Tag Manager, the Facebook Pixel has to be added manually.

The [Google Tag Manager snippet can be enabled with a nonce](https://developers.google.com/tag-manager/web/csp) along with its native tags, but custom Javascript variables cannot. Adding the Facebook Pixel snippet to Google Tag Manager manually will get you a nasty error and worst of all, the script won't run. This creates a problem.

This site uses a strong Content Security Policy and internal styles and scripts require either a hash or nonce to be loaded and executed. 

For those who are keeping up with the latest in website security and best practices, this solution won't work.

## Enter The Fix

To fix our problem, we need to first place the Facebook Pixel snippet at the end of our document, just before the closing `body` tag.

Next, we need to delay the snippet's execution until after the page has loaded by wrapping our script with the following code:

```js
  setTimeout(function(){
    /* Facebook Pixel Code */
  }, 3000);
```

Thanks, [Shay Toder](https://www.shaytoder.com/improving-page-speed-when-using-facebook-pixel/).

### Security — Client Side

We're going to add a nonce to our opening `script` tag.

*Note: If you're not generating nonces dynamically, for the purposes of this article, you can head over to [random.org](https://www.random.org/strings/) and generate a random string.*

```html
  <script nonce="4yZwhMbBbX"></script>
```

The Facebook Pixel image uses an inline style. Unfortunately, nonces don't work for inline styles. So, how do we get around this?

First let's add a class to our `img` tag like "pixel".

```html
  <noscript><img height="1" width="1" class="pixel" src="https://www.facebook.com/tr?id=YOUR_FACEBOOK_APP_ID&ev=PageView&noscript=1"/></noscript>
```

To apply our styles, we can either place the inline CSS in a `style` tag or use an external stylesheet. For the purposes of this article, we will use an internal style.

```html
  <style nonce="4yZwhMbBbX">.pixel{display:none}</style>
```

If we put it all together, you should have something that looks like this:

```html

    </footer>
    <!-- End Footer -->

    <!-- Facebook Pixel Code -->
    <script nonce="4yZwhMbBbX">
      setTimeout(function() {
          ! function(f, b, e, v, n, t, s) {
              if (f.fbq) return;
              n = f.fbq = function() {
                  n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments)
              };
              if (!f._fbq) f._fbq = n;
              n.push = n;
              n.loaded = !0;
              n.version = '2.0';
              n.queue = [];
              t = b.createElement(e);
              t.async = !0;
              t.src = v;
              s = b.getElementsByTagName(e)[0];
              s.parentNode.insertBefore(t, s)
          }(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
          fbq('init', 'XXXXXXXXXX');
          fbq('track', 'PageView');
      }, 3000);
    </script>
    <noscript><img height="1" width="1" class="pixel" src="https://www.facebook.com/tr?id=XXXXXXXXXX&ev=PageView&noscript=1"/></noscript>
    <style nonce="4yZwhMbBbX">.pixel{display:none}</style>
    <!-- End Facebook Pixel Code -->
  
  </body>
  <!-- Closing Body Tag -->

  </html>
  <!-- End Document -->

```

### Security — Server Side

Last, but not least, we need to modify our Content Security Policy header to allow external scripts from Facebook's domains. So, we'll make the following changes to our `.htaccess`—or whatever your configuration—file:

```
  Header add Content-Security-Policy " \
    style-src 'self' 'nonce-4yZwhMbBbX' connect.facebook.net; \
    script-src 'self' 'nonce-4yZwhMbBbX' connect.facebook.net; \
    img-src 'self' data:  www.facebook.com connect.facebook.net; \
    frame-src 'self' www.facebook.com; \
    frame-anscestors 'self' www.facebook.com; \
    form-action 'self' www.facebook.com/tr/ connect.facebook.net; \
    connect-src 'self' www.facebook.com; \
"
```

*Note: `connect-src` is required to allow these scripts to work in the Safari browser.*

## Results

![Facebook Pixel GT Metrix After Results](https://dev-to-uploads.s3.amazonaws.com/i/rsmmmvftmb9335zky6t2.jpg)
<figcaption>Fig 1.2 — GT Metrix results after implementing the Facebook Pixel fix.</figcaption>

1. By placing the Facebook Pixel at the end of our document, we allow our script to be loaded without interrupting our page's First Paint.
2. Delaying the execution of the script by 3 seconds: 
  * reduces our page weight by 170Kb,
  * and delays our HTTP requests so that it's not counted towards our page load time.
3. By using a Content Security Policy, we ensure that the only scripts running are those we want to run.

You can check your results over at [GT Metrix](https://gtmetrix.com) or with your browser's developer tools.

#### Resources

* [8WebDesign](https://www.8webdesign.com.au/website-speed/facebook-pixel-making-website-slower/)
* [Shay Toder](https://www.shaytoder.com/improving-page-speed-when-using-facebook-pixel/)
* [Hootesuite](https://blog.hootsuite.com/facebook-pixel/)
* [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy)