The bane of users and development teams alike, cookie banners negatively impact the user experience and can ruin page loading performance.
If a cookie banner is inserted directly into the flow of the page layout, nasty layout shift will occur, which adds up as Cumulative Layout Shift (CLS).
If a cookie banner contains a large headline or a paragraph of legalese, it may register as the Largest Contentful Paint (LCP) on a page.
Often, 3P cookie banners are added via a tag manager, making it easier for marketing teams to independently add and remove trackers. But loading a cookie banner at the end of a long request chain means it will render very late in the game.
One strategy for improving LCP in this case is to make sure the cookie banner loads sooner and use a placeholder in the layout until itβs there. The downside of this approach is that you still have JavaScript meddling in the critical rendering path.
From a user perspective, a cookie banner is definitely not critical content. Itβs arguably more important to know if the page you just landed on is the one you were looking for than how important privacy is to the website owner.
Thus, I think a better approach to implementing a 3P banner is to treat it as non-critical.
How to avoid seriously bad LCP and CLS from a cookie banner
Iβve been able to dramatically reduce LCP and avoid adding to CLS on productive websites with the following approach:
- Do: set the banner to an initial position outside of the viewport.
- Do: use JavaScript to add a class to the banner that has a CSS animation to slide it back up into the viewport
- Donβt: add the banner as part of the page layout.
Assuming youβre adding an external cookie banner via JavaScript, youβll probably plop a script into your document or use a tag manager to do it.
<script defer src=βhttps://cdn.cookie-banner-vendor.com/bundle.jsβ></script>
Use animation to slide the cookie banner up into the viewport after its initial paint
Now assuming you have some level of control over cookie banner styling, you add some custom styles for the banner to initially paint outside of the viewport and declare an animation for moving it into the viewport.
@keyframes slide-up {
0% {
transform: translateY(110vh);
}
100% {
transform: translateY(0vh);
}
}
.cookie-banner {
/* Important: Position the cookie
banner so it initially paints
outside of the viewport */
transform: translateY(110vh);
animation: slide-up 1s forwards;
}
When using multiple animations, add in classes using JS
Now if you also want to animate in a background overlay to darken the page behind the cookie banner, youβll have
@keyframes fade-in {
0% {opacity(0);}
100% {opacity(1);}
}
@keyframes slide-up {
0% {transform: translateY(110vh);}
100% {transform: translateY(0vh);}
}
/* Add this class to the cookie
banner later via JS */
.slide-up {
animation: slide-up 1s forwards;
}
.cookie-banner-overlay {
animation: fade-in 1s forwards;
}
.cookie-banner {
/* Important: Position the cookie
banner so it initially paints
outside of the viewport
and add the animation later
via JS */
transform: translateY(110vh);
}
cookieBanner.classList.add(βslide-upβ);
The performance trace shows LCP register way prior to cookie banner render and no layout shift.
Of course, this approach depends upon your ability to add custom code. If you cannot, I suggest working with your cookie banner vendor to have them optimize for performance.
Other approaches that donβt improve LCP
If you declare a CSS animation for the cookie banner to slide up, the banner will register as LCP. You donβt want that to happen.
.cookie-banner {
animation: slide-up 1s forwards;
}
Also, if you animate in the cookie banner background, donβt add animate the cookie banner into position in the same function like this:
setTimeout(() => {
bannerOverlay.classList.add("fade-in");
banner.classList.add("slide-up");
}, 1000);
Otherwise the cookie banner could end up registering as LCP.
Keep in mind the critical rendering path and where the banner paints to the screen to avoid βtossing cookiesβ π when you check your Web Vitals.