The high performance cost of Facebook Pixels

The high performance cost of Facebook Pixels

When I first started taking a deeper look into web performance one of the biggest surprises was how prevalent Facebook Pixels are, and how harmful they are for website performance.

I noticed Facebook Pixels are often one of the third-parties making the biggest performance impact on sites, only made worse by some sites including multiple different Pixels on the page. This pattern seems more common with Facebook Pixels than most other third-parties and is likely down to having multiple different departments within a business wanting to use them – resulting in organisational structure having a negative impact on user experience.

Once looking across a wider range of sites it also became clear that it is possible to use Facebook Pixels without harming performance if you avoid following the default installation instructions. I've taken a look at 60 popular sites using Facebook Pixels to understand the impact and the approaches used.

In this post I'll explore how Facebook Pixels work, the typical performance impact they cause and the different implementation options available.

What are Facebook Pixels?

Facebook Pixels are tracking scripts that can be embedded into websites which send data about user interactions through to Facebook and links this data to Facebook accounts. These have two primary benefits for businesses who advertise using Facebook – you can track what people do once they have clicked on an advert that takes them through to your site and you can use the data to target who you advertise to.

You've probably seen this in action when looking at product on a shop only to then have adverts for that same product following you around on Facebook and Instagram. This is known as remarketing.

That data is also hugely valuable for Facebook themselves, allowing them to build up a rich picture of your internet browsing habits outside of Facebook itself.

How do Facebook Pixels harm website performance?

Facebook describe a Pixel as "a few lines of code from Facebook that you copy into the header section of your website". The reality however is that those "few lines of code" are just the visible tip of the iceberg, with a lot more being loaded that isn't made quite as visible.

Overhead view of an iceberg, showing how much bigger the iceberg gets when underwater. Boat shown alongside the iceberg to highlight the size of the iceberg.
Getting a sense of the true size of an iceberg sitting under the water

How a Facebook Pixel loads

When a standard Facebook Pixel loads there are four bits of activity that typically happen.

Network timeline for https://pixely.co.uk/facebook-tracking-pixel/ showing the files related to Facebook Pixels
Waterfall from a standard Facebook Pixel installation

The blocking (synchronous) base code is an inline script you install on your site runs. This is usually in the <head> of the document, and its main purpose is to then asynchronously load a bigger script from Facebook, https://connect.facebook.net/en_US/fbevents.js

  1. The fbevents.js script, which is currently 93.4kB in size, then loads another script. This request contains your Pixel ID and is unique to your site, in the format https://connect.facebook.net/signals/config/{your pixel id}?v=2.9.33&r=stable
  2. The signals script is a currently a sizable 247kB. Once it has loaded, it can then do a number of tasks such as looking for meta data on the page and sending events through to Facebook
  3. A "PageView" event is sent, which is done by loading a GIF image with various parameters in the URL about the current page

Here's the current "base code" inline script, which I've also added to a demo page.

<!-- Facebook Pixel Code -->
<script>
  !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', '{your-pixel-id-goes-here}');
  fbq('track', 'PageView');
</script>
<noscript>
  <img height="1" width="1" style="display:none" 
       src="https://www.facebook.com/tr?id={your-pixel-id-goes-here}&ev=PageView&noscript=1"/>
</noscript>
<!-- End Facebook Pixel Code -->

Note that this also includes a <noscript> fallback option which uses an image (like a simplified version of stage 4). Be careful not to include the <noscript> element in the head of the document, as it contains an <img> element, this fallback must be within the <body> of the document – something not explained by the official documentation.

What is the performance impact?

A single Facebook Pixel currently loads just over 340kB of uncompressed JavaScript onto your page (94.7kB when compressed and transferred over the network). If we compare this to Google Analytics which is similar in terms of functionality it loads just 47.3kB of JavaScript (19kB when compressed and transferred) – so Facebook Pixels are a whooping 7x larger.

Resource SizeTransfer Size
Facebook Pixel340.4kB (93.4kB + 247kB)94.7kB (23.8kB + 70.9kB)
Google Analytics47.3kB19.0kB

I've looked at 60 popular websites which all use Facebook Pixels to get an understand of how people are using them, and what kind of impact they are having. I've used a combination of inspecting sites with browser developer tools, Lighthouse audits and public SpeedCurve data from their benchmarking pages.

For 23% of the sites, Facebook Pixels are one of their three most harmful third-parties in terms of transfer size and main thread blocking time. Usually up among integrations such as tag managers and ad networks.

Blocking the main thread means the browser is having to spend significant effort running the JavaScript, which increases the chance that your site can't respond quickly to any user interaction. If your site can't respond, users will notice and perceive your site as being slow. The exact amount of time the main thread is blocked varies a lot between sites and page loads, but on some sites it can be over 300ms. This may not sound like much, but it can be the difference that makes your site feel slow. For context, Google recommend you achieve a Total Blocking Time of less than 300ms – which covers all of your first and third party code. So if you're worried about the upcoming Core Web Vital search changes then you should definitely consider the harm of Facebook Pixels.

Not only will poor performance impact user experience, but it also increases the chance users will leave your site before your Pixel has fully loaded – meaning you may not be collecting all the data you think you are, and it may have a knock-on impact for other key functionality like site analytics or advertising.

The performance issues are exacerbated when there are multiple Pixels on a single page. 25% of the sites I looked at are using multiple Pixels. Most of those are using two, but some include even more (five pixels being the extreme 🙀). Because each one loads a unique "signals" script with your Pixel ID in it this means each Pixel needs to download it's own unique files, and each has their own impact on performance. In the worst-case, multiple Pixels are accounting for 1.3MB of JavaScript on the page.

Number of PixelsResource SizeTransfer Size
1340.4kB94.7kB
2587kB166kB
3833kB237kB
51.3MB381kB
Multiple small icebergs in the water under a cloudy sky
Multiple icebergs = multiple problems

What does Facebook say about the impact of Facebook pixel on website performance?

Tucked away at the end of the support page on the pixel developer documentation is the question "Does the Facebook pixel impact website performance?" with the following answer:

"The Facebook pixel is loaded asynchronously and does not block the display of the web page. Because all advertisers use the same pixel script, the pixel code will be already be in the browser’s cache If a user has visited any website with the pixel installed."

Facebook, February 2021 (Facebook Pixel Support)

That answer is short, but revealing. Let's deconstruct the statement a little bit.

Asynchronous loading

Whilst yes, asynchronous loading does reduce the impact on rendering it's important to note it isn't a magic bullet that means there is no performance impact at all. If you've got a framework like React or Vue which is rendering in the browser then adding in Facebook Pixels can still slow down the display of the page and cause a fight for attention with the CPU.

Browser cache

It used to be common for sites to load files from an external provider on the assumption that it meant most of the time it would already exist in the browser cache and not need to be downloaded again.

Unfortunately this is not strictly true as the behaviour varies per browser with most browsers partitioning the cache so that it is unique to your URL – meaning you won't get any benefit if the user has already downloaded that same file on another site. This has been the case in Safari since 2013, and is now also true in both Chrome and Firefox due to privacy concerns from using a shared cache.

As loading each Pixel involves loading a large JavaScript file with your Pixel ID in the URL this also means that even if a shared cache was available it wouldn't help  with Facebook Pixels as each Pixel would have it's own unique file to download.

The fbevents.js file would've benefited from a shared cache but this is no longer the case meaning all files that form part of the Pixel would need to be downloaded the first time a user visits your site.

Do they answer their own question?

Well, no. At best, the answer is misleading and at worst it's just lying about the impact. Facebook have chosen to only answer part of their question and haven't addressed issues related to the size and CPU usage of their JavaScript.

How can I use a Facebook Pixel without harming performance?

Using Facebook Pixels as recommended by Facebook only serves to harm your website performance but it is possible to use them in a way which doesn't harm performance. So what are your options?

Don't use multiple Pixels

Each Pixel you add to your site increases the impact on your performance. If you're using multiple Pixels the first step you should take is reducing this down to a single installation. This will stop you from loading quite so many files in the browser both on the initial page load and on all interaction events too.

Getting down to a single Pixel will still mean there is a performance impact, to really improve performance you'll want to try one of the two options below.

Installing using an <img> tag

Out of the 60 sites I looked at 10 of them loaded the Pixel in a completely different way which really helps minimise the performance impact. Rather than loading multiple large JavaScript files you can track most events using simple <img> requests.

Harking back to the original tracking pixels, these <img> requests typically load a 1x1px transparent GIF not because you want to display an image on the page but because it gives you a low-impact way of passing data without relying on JavaScript. This is more akin to what I think of if someone says "tracking pixel" – it feels lighter weight than "tracking script".

This is essentially how the Facebook Pixel is working underneath all of that JavaScript – it is making <img> requests back to Facebook. Bypassing their JavaScript and just using <img> requests is actually supported by Facebook, listed under their "Advanced" documentation. Although they have added a big disclaimer encouraging you not to use them.

There are a few limitations, such not being able to automatically detect click events or site microdata but aside from that you'll probably find <img> tags fulfil the majority of use cases. You can still use multiple different event types, pass through a variety of different properties and use the Pixel Helper browser extension.

Pixel TypeResource SizeTransfer Size
<img> Pixel0.297kB0.044kB
JavaScript Pixel340.4kB94.7kB

The 10 sites using <img> pixels are adding just 297 bytes per pixel, a significant reduction compared to the JavaScript approach. Crucially though, this also cuts out the intensive CPU activity down to 0 making Facebook Pixels the least impactful third-party on these sites.

Use the Conversions API

An alternative option is to use Facebook's Conversions API to track these events as API calls. This is the most involved from an implementation perspective but also gives you the most control, allowing you to limit how much data Facebook gains access to and cutting them out of your main page load entirely improving both performance and security.

With the introduction of tooling like Google Tag Manager server-side containers there are now a number of ways this is possible either with their solution or a roll-your-own approach.

The general pattern is that when an event happens on your site that you want to track you make an API call to an endpoint which you control. From this endpoint you can then make further API calls off to your selected third-parties such as Facebook. For a more detailed introduction see Simo Ahava's Server-side tagging in Google Tag Manager.

From a single API call from your site you can then fire off to multiple third-parties – so for a single page view you can then send this to both Google Analytics and Facebook Conversions API.

Summary

Facebook Pixels are surprisingly harmful for website performance and a great example of a third-party that makes an unnecessarily large number of network requests.

The documentation is misleading both in claims about performance and in the "risks" of using the <img> tag approach with a number of sites successfully using it and gaining a performance improvement through doing so. If you've got to use Facebook Pixels, the best thing you can do is use the <img> tag or Conversions API instead of the default JavaScript tracking library.


Cover photo by Annie Spratt, Iceberg photos by Dylan Shaw and Emma Francis. All on Unsplash.