Fixing Third-Party Tag Bloat
Third-party tags are the snippets that send data to analytics, advertising, heatmap, testing and chat services. Each one is added for a good reason, usually by someone outside the web team, and few are ever taken away.
Over time a site ends up with tags nobody owns, the same pixel installed twice, and scripts that fire before consent or on pages where they do nothing. This guide is about governance: finding every tag, deciding which earn their place, loading the rest through a tag manager with sensible triggers and consent rules, and controlling who can add more.
Why tags pile up
Tag bloat is an organisational problem before it is a technical one. A tag manager makes it easy for marketing, sales and agencies to add code without a developer, which is its purpose. The same ease means there is rarely a matching step for taking code away. Campaigns end, tools are replaced and agencies change, but their tags keep firing.
The costs land in several places at once:
- Speed and responsiveness. Each tag downloads and runs script on the visitor's device, and many load further scripts of their own. Work on the main thread during load and interaction affects Largest Contentful Paint and Interaction to Next Paint.
- Data quality. Duplicate tags double-count page views and conversions; tags on the wrong trigger miss events.
- Privacy compliance. Tags that set cookies or send personal data before consent can put you at odds with UK GDPR and PECR, as amended by the Data (Use and Access) Act 2025. This guide is not legal advice; check your own obligations with a qualified adviser.
- Security. A Custom HTML tag can run any code on every page, including the checkout. Anyone with publish rights effectively has that power.
defer and async on hard-coded scripts, see fixing
render-blocking scripts.Building the tag inventory
You need one list of every tag, wherever it lives. Collect from three places:
- What the browser actually loads. The JavaScript Checker lists the third-party tags on a page with their cost. Run it on your main templates and on the confirmation page after a test purchase or form submission, where conversion tags usually fire.
- What the tag manager contains. Export the container or go through the Tags list, including paused tags.
- What is hard-coded. Search the site templates, CMS header and footer settings, plugin or app settings and any "custom code" boxes for script tags.
Record each tag in a shared sheet with these columns:
| Column | Example | Why it matters |
|---|---|---|
| Tag and vendor | Heatmap tool, session recording | What it is, in words a non-developer understands. |
| Where it lives | GTM tag 14, or theme header | So you can switch it off quickly. |
| Business owner | Named person in marketing | Who decides whether it stays. |
| Purpose and report it feeds | UX review each month | If nobody uses the output, the tag has no purpose. |
| Pages and trigger | Product pages, Window Loaded | Whether it loads more widely than needed. |
| Consent category | Analytics | Which consent choice must be granted first. |
| Cost | Script size and main-thread time from the checker | Weigh against its value. |
| Review or end date | 31 March | Campaign tags should expire. |
Any tag without an owner after a reasonable chase is a candidate for removal. Pause it first rather than deleting, so it can be restored if someone turns out to need it.
Choosing when each tag loads
In a tag manager, the trigger decides not just which pages a tag runs on but when during the page load it runs. Moving a tag to a later trigger is often the easiest speed gain available, and it costs nothing in data for tags that do not need the earliest moment.
| Google Tag Manager trigger | When it fires | Suits |
|---|---|---|
| Consent Initialization | Before anything else | Consent management platform and default consent settings only. |
| Initialization | Before page view triggers | Settings that other tags depend on. |
| Page View | As soon as the container loads | Main analytics page view. |
| DOM Ready | After the HTML has been parsed | Tags that read page elements. |
| Window Loaded | After images and other resources finish | Heatmaps, secondary pixels, most marketing tags. |
| Element Visibility, Scroll Depth, Click, Timer | On a visitor action or after a delay | Chat widgets, surveys, engagement tracking. |
| Custom Event | When your code pushes an event to the data layer | Conversions such as purchase or form submission. |
Narrow the pages as well as the timing. A booking widget tag needs a trigger condition limited to booking pages; a conversion pixel needs the confirmation event, not All Pages. Set tag firing options to once per page where repeat firing makes no sense.
For heavy visible widgets such as live chat, consider a facade: a lightweight button styled like the widget, with the real script loading only when the visitor clicks it. Many chat vendors document a way to open the widget from your own button.
Consent and the tag manager
Consent handling belongs in the container, so that no tag can fire before the visitor's choice is known. The usual structure is:
- Your consent management platform loads on the Consent Initialization trigger and sets default states, denied for anything non-essential until the visitor chooses.
- Google tags read those states through consent mode, which uses the categories
ad_storage,analytics_storage,ad_user_dataandad_personalization. - Non-Google tags are given "additional consent checks" in their advanced settings, or triggers that only fire after a consent event, so they wait for the right category.
<!-- Runs before the container; defaults until the visitor chooses -->
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
wait_for_update: 500
});
Check the result in the tag manager's preview mode: load the page, decline everything, and confirm which tags fired. Then accept analytics only, and check again. The consent tab in preview mode shows the state each tag saw.
The fix, step by step
Step 1
Build a tag inventory with owners
Run the JavaScript Checker on your key templates and on a confirmation page to list the third-party tags that actually load. Add every tag from the tag manager, including paused ones, and every script hard-coded in templates, CMS settings and plugins. Put them in a shared sheet with the vendor, location, business owner, purpose, trigger, consent category, cost and a review date, and chase an owner for each unclaimed tag.
Step 2
Measure what each tag costs
Take the size and execution time of each tag from the checker. To see the real effect on the page, open DevTools, right-click a tag's request in the Network panel and block its domain, then reload and compare a Performance recording with and without it. Note tags that load many further scripts or run long tasks. Record the cost in the inventory so owners can weigh it against the value.
Step 3
Remove dead, duplicate and hard-coded tags
Pause tags with no owner, tags for tools the business has stopped paying for, and tags for finished campaigns. Where the same vendor appears twice, for example a pixel in both the theme and the container, keep one copy and remove the other. Move remaining hard-coded tags into the tag manager so all of them are governed in one place. Delete paused tags once nobody has asked for them after an agreed period.
Step 4
Give every remaining tag the right trigger
Change All Pages triggers to the specific pages each tag needs, and move tags that do not need the first moment of the load to DOM Ready or Window Loaded. Fire conversion tags on a data layer event from your own code rather than on a thank-you page view. Load chat and survey widgets on a click, timer or scroll trigger, and set firing to once per page where repeats would double-count.
Step 5
Wire consent into the container
Load your consent platform on the Consent Initialization trigger and set default consent states to denied for non-essential categories. Enable consent mode for Google tags, and give every non-Google tag an additional consent check for its category. In preview mode, decline everything and confirm only essential tags fire, then accept each category in turn and confirm the matching tags start. Take advice on your obligations; this is not legal advice.
Step 6
Restrict who can publish and what can run
Review user access in the tag manager. Give most people edit or read rights and keep publish rights to a small, named group who check changes before they go live. Limit or block Custom HTML tags where possible, using built-in templates instead, because custom code can do anything on any page. If you use a Content Security Policy, list only the tag domains you have approved so unapproved scripts are refused.
Step 7
Publish as a named version and review quarterly
Test the container in preview mode on each template, then publish with a version name and a description that lists what changed, so it can be rolled back quickly. Re-run the JavaScript Checker to confirm fewer tags and less main-thread time. Put a quarterly review in the calendar where each owner confirms their tags are still needed, and remove any that pass their review date unclaimed.
Controlling what can be added
Governance only lasts if adding a tag goes through a process. A light version that suits most small teams:
- A request form asking for the vendor, purpose, owner, pages, consent category and end date. No form, no tag.
- Workspaces for each change, so unfinished work does not get published by someone else.
- Templates over custom code. Tag manager templates for common vendors are sandboxed and declare what they are allowed to do; Custom HTML is not. In Google Tag Manager, a page can also push an allowlist or blocklist to the data layer to stop certain tag types from running at all.
- One container per site. Several containers on the same page make ownership and ordering unclear.
<!-- Before the container snippet: stop Custom HTML tags running on this site -->
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ 'gtm.blocklist': ['customScripts'] });
Test a blocklist in preview mode before publishing, because any existing tag of that type will stop firing.
Server-side tagging and other loading options
- Server-side tagging. The browser sends one stream of events to a tagging server on your own subdomain, which forwards data to each vendor. This can replace several vendor scripts in the page with one, and gives you control over what data leaves. It needs hosting and maintenance, and not every vendor supports it, so it suits sites with many marketing tags and some technical resource.
- Running tags off the main thread. Tools that move third-party scripts into a web worker exist, but compatibility varies by vendor. Test carefully and treat them as an option for specific tags, not a blanket fix.
- Edge-based tag loading. Some CDNs offer services that run third-party tools at the edge instead of in the browser. The same caveat applies: check each tool you rely on is supported.
None of these replaces removing tags that nobody needs. The cheapest tag is the one that is not there.
1. How many third-party tags is too many?
There is no official number. The right question is whether each tag has an owner, a purpose that someone acts on, and a cost that is worth it. A site with five tags that all fire on every page before consent may be in worse shape than one with fifteen that load late, on the right pages and only after consent. Use the inventory to judge each tag on its own merits, and remove anything nobody can justify.
2. Does using Google Tag Manager make my site slower?
The container itself adds a script, but the bigger effect comes from the tags inside it. A tag manager can make things faster if you use it to control when and where tags load, move non-essential tags to later triggers, and remove duplicates. It makes things slower when it becomes a place where anyone can add scripts to every page with no review. Governance, not the tool, decides which of those you get.
3. Should I move hard-coded tracking scripts into the tag manager?
Usually yes. Having every tag in one place makes it possible to see them all, apply consent rules consistently, change triggers without a developer and roll back mistakes. The exceptions are scripts that must run before the container loads, such as a consent platform that recommends direct installation, and scripts that are part of the site's functionality rather than tracking. Keep those in the template, but still record them in the inventory.
4. What is the difference between the Window Loaded and DOM Ready triggers?
DOM Ready fires once the browser has finished parsing the HTML, so page elements exist but images and other resources may still be downloading. Window Loaded fires after the page and its resources have finished loading. Moving a marketing tag from Page View to Window Loaded lets the page's own content load first. The trade-off is that a visitor who leaves very quickly may not be counted, which is acceptable for most secondary tags.
5. Are Custom HTML tags in Google Tag Manager a security risk?
They can be. A Custom HTML tag can run any JavaScript on every page it fires on, including pages with forms and payment steps. Anyone with publish rights can add one, and a compromised vendor script loaded that way runs with the same access. Keep publish rights to a small group, prefer built-in or gallery templates with declared permissions, review Custom HTML changes before publishing, and consider blocking the tag type where you do not need it.
6. Does server-side tagging remove all third-party JavaScript?
No. Something in the browser still has to collect events and send them, usually a single tag pointing at your tagging server. What server-side tagging can do is replace several vendor scripts with that one stream and let the server forward data to each vendor. Some tools, such as heatmaps, session recording and chat, need to run in the page and cannot be moved. It also brings hosting costs and maintenance, so weigh it against simply removing tags.
7. How do I check whether tags fire before cookie consent?
Open the site in a private window, open DevTools on the Network panel, and load a page without interacting with the banner. Look for requests to analytics and advertising domains and for cookies set in the Application panel. Then use the tag manager's preview mode, which shows each tag, whether it fired and the consent state it saw. Repeat after declining and after accepting each category. This is a technical check, not legal advice.
The JavaScript Checker loads your page in headless Chromium, lists the third-party tags it loads with their cost, measures size and execution time for every script and captures console errors, giving you the starting list for a tag audit.
Open JavaScript Checker Fixes โ