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
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)
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.
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!
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.
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.
Publisher Ad Audits for Lighthouse does allow cookies to be set – click on the Advanced Settings button, and paste cookie in the relevant field.
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=...
%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
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
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:
Open a guest mode window in Chrome
Load the site so the cookie banner is visible
Network panel, switch to _Offline In the
Application panel, Clear site data (it's under the Storage section), and remember to check including third-party cookies Consent to the cookies via the cookie banner
Local Storage, and Cookies to see what items have been set Take an informed guess at which of the cookies and localStorage entries set are for the consent banner
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.
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.
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