{"id":"tyklar4briy287q","title":"Reduce Total Blocking Time Without Killing Analytics","slug":"reduce-tbt-without-killing-analytics","summary":"I tackled high Total Blocking Time on a client site. Analytics scripts were the usual culprits, but killing them wasn't an option. Here's how I shaved hundreds of milliseconds off TBT without losing crucial tracking data, balancing performance with business needs.","imageUrl":"https://briancrabtree.me/images/journal-reduce-tbt-without-killing-analytics.webp","category":"Performance","date":"2026-06-19T18:00:00.000Z","featured":false,"likes":2,"author":"brian@briancrabtree.me","content":"<h2>The TBT Problem and Analytics Tax</h2>\n\n<p>A recent site audit flagged Total Blocking Time as a major drag, pushing Core Web Vitals into the red. Lighthouse scores were plummeting, and the main thread was constantly locked up. My job was clear: reduce total blocking time javascript without nuking the entire tracking stack.</p>\n\n<p>Every new tag manager snippet or third-party pixel adds overhead, often invisibly, until you run a deep performance profile. It's a cumulative tax on the user experience, where synchronous script loads or long-running tasks consistently block the main thread. Identifying these culprits was the first step.</p>\n\n<p>Clients rarely want to hear that their analytics setup is slowing down their site. They depend on that data for critical business decisions. My task wasn't to eliminate tracking, but to find a robust middle ground, keeping the lights on for marketing while making the front-end snappy for users.</p>\n\n<h2>Identifying the Blocking Scripts</h2>\n\n<p>My first step was a deep dive into Chrome DevTools performance tab. I looked for long tasks, identifiable by red triangles, especially those originating from third-party scripts. Lighthouse reports give a high-level view, but DevTools tells the actual story of main thread activity.</p>\n\n<p>Most often, the biggest offenders are tag managers or specific analytics libraries loaded directly. These scripts frequently execute heavy synchronous code or add numerous event listeners. This overhead adds up quickly, especially on slower networks, directly contributing to TBT.</p>\n\n<p>I often found that scripts meant to be loaded async were still blocking rendering due to their execution patterns. It's not just about when the script downloads, but what it does immediately upon execution. This distinction is crucial for understanding TBT.</p>\n\n<h2>Standard Async and Defer Aren't Enough</h2>\n\n<p>Simply adding async or defer attributes is the baseline, but often not enough for heavy analytics. While these prevent render-blocking, the script's execution still consumes main thread time. A deferred script might run after DOM content, but if it's computationally intensive, it will still spike TBT.</p>\n\n<p>Many tag managers, by design, need to execute early to capture certain events. This puts them in direct conflict with a low TBT target. We need a way to load them that minimizes their impact on the critical rendering path, without disabling them completely.</p>\n\n<p>The problem compounds when multiple third-party scripts are involved. Even if individually optimized, their cumulative execution can create a 'thundering herd' problem, all vying for main thread access. We needed more granular control over script execution.</p>\n\n<h2>Leveraging RequestIdleCallback and SetTimeout</h2>\n\n<p>To truly reduce Total Blocking Time, I moved critical-but-non-essential analytics script execution off the main thread's immediate queue. requestIdleCallback became my go-to for deferring less time-sensitive tasks, scheduling work during browser idle periods.</p>\n\n<p>For scripts that absolutely had to run, but not immediately, setTimeout(..., 0) or slightly longer delays proved effective. This pushes script execution to the next available event loop tick, breaking up long tasks into smaller, manageable chunks. It's a simple, powerful trick.</p>\n\n<p>This approach bought us significant breathing room. Instead of a single, massive blocking task, we saw a series of smaller, non-blocking tasks. We maintained tracking accuracy while drastically improving perceived performance, making the site feel much more responsive.</p>\n\n<h2>Selective Loading and Event Delegation</h2>\n\n<p>Another technique was to selectively load analytics scripts only when truly needed, or after a user interaction. For instance, a chatbot script doesn't need to load until a user clicks its icon. This saves valuable initial load time and reduces TBT.</p>\n\n<p>Event delegation also played a key role in optimizing event listeners added by analytics. Instead of attaching a listener to every interactive element, I delegated them to a higher common ancestor. This dramatically reduces DOM overhead and initial script execution time for tracking setup.</p>\n\n<p>For pages where certain analytics were critical from the start, we prioritized those and deferred others. This isn't about killing analytics; it's about being strategic. We apply this thinking for the briancrabtree.me journal too, much like how I discuss optimizing assets in /journal/asset-optimization-strategies/, ensuring core metrics are always captured.</p>\n\n<h2>Managing Third-Party Tag Managers</h2>\n\n<p>Third-party tag managers are often the biggest contributors to Total Blocking Time due to their dynamic nature. They can inject arbitrary scripts and styles, often without much thought for performance. My strategy here was aggressive consolidation and strict auditing.</p>\n\n<p>We removed any redundant or unused tags from the tag manager container. It sounds obvious, but you'd be surprised how many stale tags accumulate over time. Each one is a potential TBT bomb, even if it's just a tiny pixel. Regular cleanup is essential.</p>\n\n<p>For tags that absolutely had to remain, I pushed for defer and async options within the tag manager configuration, if available. Some platforms offer better control. When that failed, I explored custom templates or server-side tag management where possible, offloading client-side work.</p>\n\n<h2>What I Do Next</h2>\n\n<p>Ongoing monitoring is not optional. Performance metrics shift constantly, especially with updates to third-party scripts or new marketing campaigns. I keep Lighthouse, PageSpeed Insights, and Real User Monitoring (RUM) tools running to catch regressions early.</p>\n\n<p>The goal is a constant balance between data needs and user experience. It's a continuous optimization cycle, not a one-off fix. I regularly review all third-party dependencies and challenge their necessity versus their performance cost.</p>\n\n<p>If you’re wrestling with a similar problem, especially regarding the overhead of marketing tags, you might find my thoughts on the associated costs helpful. Check out my article on the performance tax of tag managers: /journal/tag-manager-performance-tax/.</p>","tags":["tbt","javascript","analytics"],"views":3}