Webclat logoWebclat . | OneTrust Solutions
CMP performance

How do I load a CMP/consent banner without it becoming the slowest script on the page?

Short answer

Most consent-banner performance problems come from loading the full CMP script synchronously in a way that blocks rendering, or from a single request that bundles a large vendor/cookie database together with the visible banner UI - split the two: a tiny, synchronous script that sets Consent Mode defaults and gates other tags, loaded first, with the heavier CMP library itself deferred to load asynchronously after that.

Why this happens

There are two distinct performance costs, and they need different fixes. The first is render-blocking: a plain <script src="..."> in the document head without async or defer stops the browser from continuing to parse and paint the page until that script has downloaded and executed. The second is genuine payload size: some CMP vendors ship a large bundled dataset (every possible vendor's cookie declarations, multiple language packs) in their default hosted script, which is a real amount of JavaScript to parse and execute regardless of loading strategy.

Fix it

  1. 1

    Load the CMP's core library with async or defer, never a plain blocking tag

    A blocking <script src> in <head> is the single most common and most fixable cause of a CMP showing up as a render-blocking resource in performance audits.

  2. 2

    Set Consent Mode defaults with a tiny, separate, synchronous script

    The default-denied signal needs to run before any other tag can load, but it only needs to be a few lines - not the whole CMP library. Keep it as its own minimal inline script that runs first, with the full banner UI/library following asynchronously.

    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){ dataLayer.push(arguments); }
      gtag('consent', 'default', {
        analytics_storage: 'denied',
        ad_storage: 'denied',
        ad_user_data: 'denied',
        ad_personalization: 'denied',
        wait_for_update: 500
      });
    </script>
    <script async src="/path/to/full-cmp-library.js"></script>
  3. 3

    Check whether your CMP vendor offers a lighter-weight mode

    Some vendors' fully-hosted script is large because it bundles every possible integration's vendor-cookie declarations by default - check for a self-hosted, scoped-down, or "lite" configuration option that ships only what your actual vendor list needs.

  4. 4

    Defer the visible banner's render until after first paint

    Many CMP libraries support a configuration flag to delay rendering the visible banner UI until the page's main content has painted, rather than blocking first paint on banner readiness - use it if available.

  5. 5

    Measure with a real performance audit before and after, not just page-load feel

    Run Lighthouse or PageSpeed Insights specifically looking at the "render-blocking resources" and "reduce unused JavaScript" flags, since CMP scripts commonly show up under exactly those two categories when misconfigured.

How to verify it worked

Run Lighthouse before and after the change and confirm the CMP script no longer appears in the render-blocking-resources list.

Compare Largest Contentful Paint timing with the banner present against a build with it temporarily stripped out, to confirm it isn't regressing LCP once loaded asynchronously.

Confirm the tiny synchronous default-consent script still runs before any gated tag, even with the full CMP library now loading asynchronously - check DevTools Network waterfall ordering to be sure the sequencing wasn't broken by the change.

Related

Still stuck, or want this checked against your specific setup?

We scope every engagement in discovery, before implementation - no assumptions about your stack.

Request a Free OneTrust Audit