Andy Davies

Independent Web Performance Consultant

Bypassing Cookie Consent Banners in Lighthouse and WebPageTest

When it comes to testing pages using Lighthouse, WebPageTest or other similar tools, cookie and similar consent banners are a pain!

They can cause layout shifts, on mobile the banner is sometimes the element for Largest Contentful Paint (LCP), they visually obscure other parts of the page, and if implemented correctly only some of the page's resources will be fetched.

When analysing sites one of my first steps is to work out how to bypass any consent banners so I can get a more complete view of page performance.

This post covers some of the performance issues related to consent banners, how I bypass the banners, and my approach to working out which cookies or localStorage items I need to set to bypass them.

Simon Hearne wrote about Measuring Performance behind Content Popups in May 2020, and while there's some overlap I'd recommend you read Simon's post too.

Challenges that Banners Bring

Layout Shifts

Some banners are displayed at the top of the page before other content and there's a danger that if the banner is inserted after rendering starts, the content below them will shift downwards.

In a filmstrip of gov.uk there's layout shift at 0.7s when the consent banner is displayed (they have plans to address the issue in the future)

Filmstrip showing the layout shift when the consent banner loads on gov.uk gov.uk – London, Chrome, Cable

One way of eliminating this shift would be to adopt the approach Zach Leatherman took with a banner on Netlify and include them directly in page but hide then when they're not required.

Another is to use a pop-over approach where the consent banner is positioned over the page content.

Largest Contentful Paint

On some pages, and particularly on mobile, parts of the consent banner get detected as the Largest Content Paint.

Currys PC World have this issue on their category pages, but not on their product pages, so removing the banner is important if we want get comparable measurements between the different page types.

Filmstrip showing the cookie banner as Largest Contentful Paint on currys.co.uk Currys PC World – London, Chrome, Cable

There are other sites with very similar banners but yet another element is counted as the Largest Contentful Paint, so checking which element is being used is important.

Obscure Key Content

Filmstrips are a powerful way to convey performance to anyone regardless of their web performance knowledge and I rely on them to help clients understand what the current experience and to demonstrate how it improves as optimisations are implemented.

And as consent banners can cover up the key content, they just get in the way!

Partial Measurement

In countries where opt-in consent is required for 3rd-party data collection, the banner should delay the load of such scripts until consent is given.

These extra scripts influence performance – at the very least they'll increase the total bytes downloaded but often they'll also introduce long tasks, layout shifts and other behaviour that affects performance metrics too.

Bypassing Cookie Consent

Some sites add a 'developer option' to their consent banners, for example a query string parameter that prevents the banner from being displayed.

This makes testing with and without consent banners much easier but often this option doesn't exist, and sometimes banners are provided by a third-party services so typically in these cases cookies need to be set to avoid them.

Lighthouse

By default, Lighthouse doesn't support cookies, so web.dev/measure, Page Speed Insights etc. will test the site with the consent banner shown.

And if the consent banner is configured correctly then in opt-in e.g. GDPR, regions the Lighthouse score will be based on a partial page load i.e. without any 3rd-party tags.

But Publisher Ad Audits for Lighthouse does allow cookies to be set – click on the Advanced Settings button, and paste cookie in the relevant field.

Screenshot of Lighthouse for Ads

If you need a score or advice on how to improve using this version of Lighthouse is a quick way to get that.

Cookies can also be set in Lighthouse CLI and CI

WebPageTest

Often I want more than Lighthouse provides…

I want waterfalls so I can dig into network performance, filmstrips to demonstrate the benefits of optimisations, and Request Maps help understand the 3rd-parties on a page.

And most of the time I use WebPageTest to generate this data with one of these two approaches for bypassing consent banners.

I either set cookies via the setCookie script command:

setCookie https://%HOST% cookie_name=...
navigate %URL%

Note: %URL% and %HOST% are WebPageTest script variables that will be replaced with the relevant part of the URL being tested. One day I'll submit a PR to add %ORIGIN% so https://%HOST% can be replaced with something more friendly.

Or via an injected script:

document.cookie='cookie_name=...';

Something to consider is there's a slight timing difference as to when the cookie is set between the two WebPageTest approaches.

In the first approach, the cookie is set before navigation, so the cookie is available to any inline scripts that are early in the page, or any server-side processes that might generate an inline cookie banner.

Whereas the second approach sets the cookie after the browser starts to receive the HTML content, which might be too late for some cookie banners but allows extra commands such as setting localStorage items to be added.

Another advantage of the injected script approach is the script can also be tested in the DevTools console – clear storage, execute the script in the console, then reload the page and if the script's correct the consent banner shouldn't appear.

Sometimes Cookies aren't Enough

Some consent banners – IAB EU Consent Management Providers (CMPs) such as Quantcast Choice – also use local storage so just setting cookies isn't enough to bypass them.

To bypass these types of consent banners, I rely on injecting a custom script in WebPageTest.

For Quantcast Choice, the injected script looks like this (values omitted):

localStorage.setItem('CMPList', '...');
localStorage.setItem('noniabvendorconsent', '...');
localStorage.setItem('_cmpRepromptHash', '...');
document.cookie = 'euconsent-v2=...;'
document.cookie = 'addtl_consent=...;'

Creating these scripts for each site that uses Quantcast got pretty boring pretty quickly, so I've started using a DevTools snippet to generate the script.

Running the snippet in DevTools produces a script ready to paste into WebPageTest's Inject Script field (which is at the bottom of the Advanced tab)

I'll probably add snippets for other common CMPs as I come across them at clients and prospects, but Pull Requests are also very welcome!

Determining the Combination of Cookies and localStorage Items

One remaining challenge is determining which cookies, and localStorage items need to be set.

Originally I relied on a combination of trial and error – inspecting storage, debugging minified scripts in DevTools and then testing in DevTools and WebPageTest – to work this out.

But one day, while lying awake in the early hours, I realised there might be an easier way to determine what's needed, and so now my process starts like this:

  1. Open a guest mode window in Chrome
  2. Open DevTools
  3. Load the site so the cookie banner is visible
  4. In DevTools Network panel, switch to _Offline
  5. In the Application panel, Clear site data (it's under the Storage section), and remember to check including third-party cookies
  6. Consent to the cookies via the cookie banner
  7. Inspect Local Storage, and Cookies to see what items have been set
  8. Take an informed guess at which of the cookies and localStorage entries set are for the consent banner
  9. Write a script and test it

It's not a foolproof method, but it's certainly helped me get a head start with many sites I analyse.

Some sites make a network request as part of the consent process, and this fails in offline mode so not all the cookies and localStorage items get set – The Guardian is one site that throws up this issue.

Wrapping Up

Although I've concentrated on bypassing consent banners, testing with them in place is still important as it helps to understand our visitors' initial experience.

After all, if our visitors have a bad initial experience they may abandon without even interacting with the consent banner.

One thing I've noticed across multiple sites is how late many consent banners load – sometimes banner's are delayed because they depend on an external script loading, other times they wait for events such as DOMContentLoaded before being shown.

I'm not sure whether the aim should be to display the consent banner as soon as possible, or whether displaying content and then covering it with a banner is OK, and I couldn't find any research that helped clarify the issue.

Tests that display a consent banner only provide a partial view – particularly when testing is done from countries that require opt-in – so bypassing the banner helps us to build a more complete view of performance within testing and monitoring processes.

Revisiting the page from Currys when consent has been given; the Largest Contentful Paint gets faster, there's not much difference in Total Blocking Time, but the tags that execute introduce several Layout Shifts.

Comparison of Largest Contentful Paint and Total Blocking Time with and without Consent Banner

Comparison of Cumulative Layout Shift with and without Consent Banner

The full comparison of the Currys page with and without the Consent Banner is available on WebPageTest.

Although I've focused on Lighthouse and WebPageTest, the techniques for determining what cookies (and localStorage items) are needed to bypass consent banners should also work with other tools – many support setting headers and some, DebugBear for example, support injecting scripts.

Further Reading

Measuring Performance behind consent popups, Simon Hearne, May 2020

Publisher Ad Audits for Lighthouse

Ruthlessly Eliminating Layout Shift on netlify.com, Zach Leatherman, Nov 2020

WebPageTest Cookie Consent Scripts

Comments