[{"data":1,"prerenderedAt":1025},["ShallowReactive",2],{"content:\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight":3,"surroundings:\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight":1017},{"id":4,"title":5,"body":6,"description":997,"extension":998,"meta":999,"navigation":1011,"path":1012,"seo":1013,"stem":1015,"__hash__":1016},"content\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight\u002Findex.md","Auditing Google Tag Manager Container Weight",{"type":7,"value":8,"toc":981},"minimark",[9,14,29,32,126,131,179,183,189,195,205,211,316,320,325,328,559,562,566,569,573,593,684,687,691,698,800,804,815,819,822,826,854,858,864,870,876,882,886,898,912,921,930,939,943,966,971,974,977],[10,11,13],"h1",{"id":12},"how-to-audit-google-tag-manager-container-weight","How to Audit Google Tag Manager Container Weight",[15,16,17,18,23,24,28],"p",{},"This guide is a hands-on audit within ",[19,20,22],"a",{"href":21},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002F","Third-Party Script Performance",", part of ",[19,25,27],{"href":26},"\u002Fjavascript-bundle-optimization-code-splitting\u002F","JavaScript Bundle Optimization & Code Splitting",". Google Tag Manager is often the single largest source of third-party JavaScript on a site, and the hardest to see: the container is configured in a web UI by people outside engineering, tags are added for campaigns and rarely removed, and every tag that fires on \"All Pages\" runs on every page view.",[15,30,31],{},"The container file itself grows with every tag, trigger and variable — 100–300KB is common for mature containers — and that is before the tags it injects load their own scripts. The execution cost lands on the main thread around page load and, through click and form triggers, inside user interactions. An audit makes the cost visible per tag, finds what can be removed, and moves the rest off the critical path.",[15,33,34],{},[35,36,42,43,42,50,42,54,42,57,42,66,42,72,42,80,42,86,42,92,42,96,42,100,42,103,42,109,42,113,42,116,42,119,42,123,42],"svg",{"viewBox":37,"width":38,"role":39,"ariaLabel":40,"style":41},"0 0 760 268","100%","img","The layers that make up the cost of a Google Tag Manager setup, from the container file to the tags' own scripts and their triggers.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[44,45],"rect",{"className":46,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],"svg-canvas","0","#ffffff",[51,52,53],"title",{},"Layers of GTM cost",[55,56,40],"desc",{},[44,58],{"x":59,"y":59,"width":60,"height":61,"rx":62,"fill":63,"stroke":64,"style":65},"1","758","266","10","none","currentColor","stroke-opacity:0.18",[67,68,53],"text",{"x":69,"y":70,"fill":64,"style":71},"28.0","34.0","font-size:16px;font-weight:700",[44,73],{"x":69,"y":74,"width":75,"height":76,"rx":77,"fill":78,"stroke":78,"style":79},"56.0","704.0","40.0","6","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[67,81,85],{"x":82,"y":83,"fill":64,"style":84},"42.0","80.5","font-size:13px;font-weight:700","Container (gtm.js)",[67,87,91],{"x":88,"y":83,"fill":64,"style":89,"textAnchor":90},"199.4","font-size:12px","start","size grows with every tag, trigger and variable — downloaded and parsed on every page",[44,93],{"x":69,"y":94,"width":75,"height":76,"rx":77,"fill":64,"stroke":64,"style":95},"106.0","fill-opacity:0.06;stroke-opacity:0.4",[67,97,99],{"x":82,"y":98,"fill":64,"style":84},"130.5","Built-in tags",[67,101,102],{"x":88,"y":98,"fill":64,"style":89,"textAnchor":90},"GA4, custom HTML — execute inside the container's tasks",[44,104],{"x":69,"y":105,"width":75,"height":76,"rx":77,"fill":106,"stroke":107,"style":108},"156.0","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[67,110,112],{"x":82,"y":111,"fill":64,"style":84},"180.5","Injected vendor scripts",[67,114,115],{"x":88,"y":111,"fill":64,"style":89,"textAnchor":90},"pixels, heatmaps, chat, testing tools — each with its own download and execution",[44,117],{"x":69,"y":118,"width":75,"height":76,"rx":77,"fill":78,"stroke":78,"style":79},"206.0",[67,120,122],{"x":82,"y":121,"fill":64,"style":84},"230.5","Triggers",[67,124,125],{"x":88,"y":121,"fill":64,"style":89,"textAnchor":90},"click, form, scroll and timer triggers attach listeners that run during interactions",[127,128,130],"h2",{"id":129},"rapid-diagnosis","Rapid Diagnosis",[132,133,134,147,157,167,173],"ul",{},[135,136,137,141,142,146],"li",{},[138,139,140],"strong",{},"Measure the container file."," Network panel: ",[143,144,145],"code",{},"gtm.js?id=GTM-XXXX"," transfer and decoded size.",[135,148,149,152,153,156],{},[138,150,151],{},"Count injected requests."," Filter by initiator ",[143,154,155],{},"gtm.js"," or by third-party domains; note bytes and requests.",[135,158,159,162,163,166],{},[138,160,161],{},"Profile main-thread cost."," In a throttled trace, group Bottom-Up by domain; attribute ",[143,164,165],{},"googletagmanager.com"," and the vendors it loads.",[135,168,169,172],{},[138,170,171],{},"Use Tag Assistant \u002F preview mode"," to list tags fired on a page view and on common interactions.",[135,174,175,178],{},[138,176,177],{},"Export the container JSON"," (Admin → Export Container) to audit tags, triggers and variables offline.",[127,180,182],{"id":181},"root-cause-analysis","Root Cause Analysis",[15,184,185,188],{},[138,186,187],{},"1. Tag accumulation."," Campaign pixels, retired A\u002FB tests and duplicate analytics tags pile up; nobody owns removal.",[15,190,191,194],{},[138,192,193],{},"2. \"All Pages\" triggers."," Tags needed on a few pages fire everywhere.",[15,196,197,200,201,204],{},[138,198,199],{},"3. Custom HTML tags."," Arbitrary script injected synchronously, often with ",[143,202,203],{},"document.write"," or heavy inline code.",[15,206,207,210],{},[138,208,209],{},"4. Interaction triggers."," \"All Elements\" click triggers and form listeners run on every click, adding processing time to interactions — directly visible in INP.",[15,212,213],{},[35,214,42,217,42,220,42,223,42,225,42,228,42,230,42,240,42,247,42,255,42,260,42,264,42,268,42,272,42,276,42,280,42,284,42,288,42,292,42,296,42,300,42,305,42,309,42],{"viewBox":215,"width":38,"role":39,"ariaLabel":216,"style":41},"0 0 760 247","Bar chart of main-thread time attributed to individual tags loaded through a Google Tag Manager container.",[44,218],{"className":219,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,221,222],{},"Main-thread time by GTM-managed tag (mid-tier phone, page load)",[55,224,216],{},[44,226],{"x":59,"y":59,"width":60,"height":227,"rx":62,"fill":63,"stroke":64,"style":65},"245",[67,229,222],{"x":69,"y":70,"fill":64,"style":71},[231,232],"line",{"x1":233,"y1":234,"x2":233,"y2":235,"stroke":107,"strokeWidth":236,"strokeDashArray":237,"style":239},"333.6","72.0","225.0","1.5",[238,238],"4","stroke-opacity:0.9",[67,241,246],{"x":242,"y":243,"fill":64,"style":244,"textAnchor":245},"175.0","92.0","font-size:13px","end","Container evaluation",[44,248],{"x":249,"y":250,"width":251,"height":252,"rx":253,"fill":106,"stroke":107,"style":254},"187.0","78.0","258.1","19","3","fill-opacity:0.7;stroke-opacity:0.9",[67,256,259],{"x":257,"y":243,"fill":64,"style":258},"451.1","font-size:12px;font-weight:600","88ms",[67,261,263],{"x":242,"y":262,"fill":64,"style":244,"textAnchor":245},"123.0","Heatmap \u002F session replay",[44,265],{"x":249,"y":266,"width":267,"height":252,"rx":253,"fill":106,"stroke":107,"style":254},"109.0","481.0",[67,269,271],{"x":270,"y":262,"fill":64,"style":258},"674.0","164ms",[67,273,275],{"x":242,"y":274,"fill":64,"style":244,"textAnchor":245},"154.0","Two ad pixels",[44,277],{"x":249,"y":278,"width":279,"height":252,"rx":253,"fill":106,"stroke":107,"style":254},"140.0","211.2",[67,281,283],{"x":282,"y":274,"fill":64,"style":258},"404.2","72ms",[67,285,287],{"x":242,"y":286,"fill":64,"style":244,"textAnchor":245},"185.0","Legacy A\u002FB test (ended)",[44,289],{"x":249,"y":290,"width":291,"height":252,"rx":253,"fill":106,"stroke":107,"style":254},"171.0","170.1",[67,293,295],{"x":294,"y":286,"fill":64,"style":258},"363.1","58ms",[67,297,299],{"x":242,"y":298,"fill":64,"style":244,"textAnchor":245},"216.0","GA4",[44,301],{"x":249,"y":302,"width":303,"height":252,"rx":253,"fill":64,"stroke":64,"style":304},"202.0","120.2","fill-opacity:0.7;stroke-opacity:0.4",[67,306,308],{"x":307,"y":298,"fill":64,"style":258},"313.2","41ms",[67,310,315],{"x":233,"y":311,"fill":312,"style":313,"textAnchor":314},"68.0","#8a6608","font-size:12px;font-weight:700","middle","50ms",[127,317,319],{"id":318},"step-by-step-audit","Step-by-Step Audit",[321,322,324],"h3",{"id":323},"_1-inventory-tags-with-owners-and-purpose","1. Inventory tags with owners and purpose",[15,326,327],{},"From the exported JSON, list every tag with its type, triggers and last-modified date. Ask an owner for each; anything without an owner or purpose is a removal candidate.",[329,330,335],"pre",{"className":331,"code":332,"language":333,"meta":334,"style":334},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F node audit-gtm.mjs container.json — list tags with triggers.\nimport fs from 'node:fs';\nconst c = JSON.parse(fs.readFileSync(process.argv[2], 'utf8')).containerVersion;\nconst triggers = Object.fromEntries((c.trigger ?? []).map((t) => [t.triggerId, t.name]));\nfor (const t of c.tag ?? []) {\n  console.log([t.name, t.type, (t.firingTriggerId ?? []).map((id) => triggers[id] ?? id).join(' | ')].join('\\t'));\n}\n\u002F\u002F trade-off: the export does not show what each tag injects at runtime.\n\u002F\u002F Combine this list with a network capture per page type to see real cost.\n","javascript","",[143,336,337,345,366,410,454,479,541,547,553],{"__ignoreMap":334},[338,339,341],"span",{"class":231,"line":340},1,[338,342,344],{"class":343},"sjfSM","\u002F\u002F node audit-gtm.mjs container.json — list tags with triggers.\n",[338,346,348,352,356,359,363],{"class":231,"line":347},2,[338,349,351],{"class":350},"sPARh","import",[338,353,355],{"class":354},"saISM"," fs ",[338,357,358],{"class":350},"from",[338,360,362],{"class":361},"sZ8jY"," 'node:fs'",[338,364,365],{"class":354},";\n",[338,367,369,372,376,379,382,385,389,392,395,398,401,404,407],{"class":231,"line":368},3,[338,370,371],{"class":350},"const",[338,373,375],{"class":374},"sPXB4"," c",[338,377,378],{"class":350}," =",[338,380,381],{"class":374}," JSON",[338,383,384],{"class":354},".",[338,386,388],{"class":387},"smZ65","parse",[338,390,391],{"class":354},"(fs.",[338,393,394],{"class":387},"readFileSync",[338,396,397],{"class":354},"(process.argv[",[338,399,400],{"class":374},"2",[338,402,403],{"class":354},"], ",[338,405,406],{"class":361},"'utf8'",[338,408,409],{"class":354},")).containerVersion;\n",[338,411,413,415,418,420,423,426,429,432,435,438,441,445,448,451],{"class":231,"line":412},4,[338,414,371],{"class":350},[338,416,417],{"class":374}," triggers",[338,419,378],{"class":350},[338,421,422],{"class":354}," Object.",[338,424,425],{"class":387},"fromEntries",[338,427,428],{"class":354},"((c.trigger ",[338,430,431],{"class":350},"??",[338,433,434],{"class":354}," []).",[338,436,437],{"class":387},"map",[338,439,440],{"class":354},"((",[338,442,444],{"class":443},"sQw3B","t",[338,446,447],{"class":354},") ",[338,449,450],{"class":350},"=>",[338,452,453],{"class":354}," [t.triggerId, t.name]));\n",[338,455,457,460,463,465,468,471,474,476],{"class":231,"line":456},5,[338,458,459],{"class":350},"for",[338,461,462],{"class":354}," (",[338,464,371],{"class":350},[338,466,467],{"class":374}," t",[338,469,470],{"class":350}," of",[338,472,473],{"class":354}," c.tag ",[338,475,431],{"class":350},[338,477,478],{"class":354}," []) {\n",[338,480,482,485,488,491,493,495,497,499,502,504,506,509,511,514,517,520,523,526,528,530,533,536,538],{"class":231,"line":481},6,[338,483,484],{"class":354},"  console.",[338,486,487],{"class":387},"log",[338,489,490],{"class":354},"([t.name, t.type, (t.firingTriggerId ",[338,492,431],{"class":350},[338,494,434],{"class":354},[338,496,437],{"class":387},[338,498,440],{"class":354},[338,500,501],{"class":443},"id",[338,503,447],{"class":354},[338,505,450],{"class":350},[338,507,508],{"class":354}," triggers[id] ",[338,510,431],{"class":350},[338,512,513],{"class":354}," id).",[338,515,516],{"class":387},"join",[338,518,519],{"class":354},"(",[338,521,522],{"class":361},"' | '",[338,524,525],{"class":354},")].",[338,527,516],{"class":387},[338,529,519],{"class":354},[338,531,532],{"class":361},"'",[338,534,535],{"class":350},"\\t",[338,537,532],{"class":361},[338,539,540],{"class":354},"));\n",[338,542,544],{"class":231,"line":543},7,[338,545,546],{"class":354},"}\n",[338,548,550],{"class":231,"line":549},8,[338,551,552],{"class":343},"\u002F\u002F trade-off: the export does not show what each tag injects at runtime.\n",[338,554,556],{"class":231,"line":555},9,[338,557,558],{"class":343},"\u002F\u002F Combine this list with a network capture per page type to see real cost.\n",[15,560,561],{},"Expected outcome: a spreadsheet of tags, triggers, owners and status.",[321,563,565],{"id":564},"_2-measure-each-tags-runtime-cost","2. Measure each tag's runtime cost",[15,567,568],{},"Use preview mode with a throttled trace, or temporarily pause tags in a workspace and compare traces. Record bytes and main-thread milliseconds per tag on your heaviest template.",[321,570,572],{"id":571},"_3-remove-narrow-and-defer","3. Remove, narrow and defer",[132,574,575,581,587],{},[135,576,577,580],{},[138,578,579],{},"Remove"," tags for ended campaigns and experiments, duplicates, and tags without owners.",[135,582,583,586],{},[138,584,585],{},"Narrow"," \"All Pages\" triggers to the pages that need them.",[135,588,589,592],{},[138,590,591],{},"Defer"," non-essential tags to \"Window Loaded\" plus a timer, or fire them from a custom event dispatched after the page is idle.",[329,594,596],{"className":331,"code":595,"language":333,"meta":334,"style":334},"\u002F\u002F Fire a custom event after load + idle; use it as the trigger for non-critical tags.\naddEventListener('load', () => requestIdleCallback(() => {\n  window.dataLayer = window.dataLayer || [];\n  window.dataLayer.push({ event: 'idle_ready' });\n}, { timeout: 4000 }));\n\u002F\u002F trade-off: tags on idle_ready miss users who leave within the first seconds.\n\u002F\u002F Keep conversion-critical tags on page view; move only non-critical ones.\n",[143,597,598,603,629,646,663,674,679],{"__ignoreMap":334},[338,599,600],{"class":231,"line":340},[338,601,602],{"class":343},"\u002F\u002F Fire a custom event after load + idle; use it as the trigger for non-critical tags.\n",[338,604,605,608,610,613,616,618,621,624,626],{"class":231,"line":347},[338,606,607],{"class":387},"addEventListener",[338,609,519],{"class":354},[338,611,612],{"class":361},"'load'",[338,614,615],{"class":354},", () ",[338,617,450],{"class":350},[338,619,620],{"class":387}," requestIdleCallback",[338,622,623],{"class":354},"(() ",[338,625,450],{"class":350},[338,627,628],{"class":354}," {\n",[338,630,631,634,637,640,643],{"class":231,"line":368},[338,632,633],{"class":354},"  window.dataLayer ",[338,635,636],{"class":350},"=",[338,638,639],{"class":354}," window.dataLayer ",[338,641,642],{"class":350},"||",[338,644,645],{"class":354}," [];\n",[338,647,648,651,654,657,660],{"class":231,"line":412},[338,649,650],{"class":354},"  window.dataLayer.",[338,652,653],{"class":387},"push",[338,655,656],{"class":354},"({ event: ",[338,658,659],{"class":361},"'idle_ready'",[338,661,662],{"class":354}," });\n",[338,664,665,668,671],{"class":231,"line":456},[338,666,667],{"class":354},"}, { timeout: ",[338,669,670],{"class":374},"4000",[338,672,673],{"class":354}," }));\n",[338,675,676],{"class":231,"line":481},[338,677,678],{"class":343},"\u002F\u002F trade-off: tags on idle_ready miss users who leave within the first seconds.\n",[338,680,681],{"class":231,"line":543},[338,682,683],{"class":343},"\u002F\u002F Keep conversion-critical tags on page view; move only non-critical ones.\n",[15,685,686],{},"Expected outcome: fewer tags at load, and the remaining non-critical ones out of the startup window.",[321,688,690],{"id":689},"_4-replace-interaction-triggers-that-run-on-every-click","4. Replace interaction triggers that run on every click",[15,692,693,694,697],{},"Swap \"All Elements\" click triggers for narrowly scoped ones (specific CSS selectors), and push explicit ",[143,695,696],{},"dataLayer"," events from your own code for important interactions. That removes container work from every unrelated click's processing time.",[15,699,700],{},[35,701,42,704,42,707,42,710,42,712,42,715,42,717,42,721,42,726,42,730,42,733,42,736,42,740,42,743,42,747,42,751,42,754,42,758,42,762,42,767,42,771,42,775,42,780,42,782,42,785,42,788,42,791,42,794,42,797,42],{"viewBox":702,"width":38,"role":39,"ariaLabel":703,"style":41},"0 0 760 318","Four steps of a Google Tag Manager container audit from inventory to scoped triggers.",[44,705],{"className":706,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,708,709],{},"GTM audit sequence",[55,711,703],{},[44,713],{"x":59,"y":59,"width":60,"height":714,"rx":62,"fill":63,"stroke":64,"style":65},"316",[67,716,709],{"x":69,"y":70,"fill":64,"style":71},[44,718],{"x":234,"y":74,"width":719,"height":720,"rx":77,"fill":78,"stroke":78,"style":79},"660.0","51.0",[67,722,725],{"x":723,"y":724,"fill":64,"style":84,"textAnchor":90},"86.0","77.0","Inventory and assign owners",[67,727,729],{"x":723,"y":728,"fill":64,"style":89,"textAnchor":90},"94.0","Export container JSON; every tag needs an owner and purpose",[44,731],{"x":234,"y":732,"width":719,"height":720,"rx":77,"fill":78,"stroke":78,"style":79},"119.0",[67,734,735],{"x":723,"y":278,"fill":64,"style":84,"textAnchor":90},"Measure cost per tag",[67,737,739],{"x":723,"y":738,"fill":64,"style":89,"textAnchor":90},"157.0","Throttled traces with tags paused one at a time",[44,741],{"x":234,"y":742,"width":719,"height":720,"rx":77,"fill":78,"stroke":78,"style":79},"182.0",[67,744,746],{"x":723,"y":745,"fill":64,"style":84,"textAnchor":90},"203.0","Remove, narrow, defer",[67,748,750],{"x":723,"y":749,"fill":64,"style":89,"textAnchor":90},"220.0","Dead tags out; page-scoped triggers; idle_ready for non-critical",[44,752],{"x":234,"y":753,"width":719,"height":720,"rx":77,"fill":78,"stroke":78,"style":79},"245.0",[67,755,757],{"x":723,"y":756,"fill":64,"style":84,"textAnchor":90},"266.0","Scope interaction triggers",[67,759,761],{"x":723,"y":760,"fill":64,"style":89,"textAnchor":90},"283.0","Selector-specific clicks or explicit dataLayer events",[231,763],{"x1":764,"y1":765,"x2":764,"y2":98,"stroke":64,"strokeWidth":236,"style":766},"43.0","95.5","stroke-opacity:0.3",[231,768],{"x1":764,"y1":769,"x2":764,"y2":770,"stroke":64,"strokeWidth":236,"style":766},"158.5","193.5",[231,772],{"x1":764,"y1":773,"x2":764,"y2":774,"stroke":64,"strokeWidth":236,"style":766},"221.5","256.5",[776,777],"circle",{"cx":764,"cy":778,"r":779,"fill":78},"81.5","13",[67,781,59],{"x":764,"y":723,"fill":49,"style":84,"textAnchor":314},[776,783],{"cx":764,"cy":784,"r":779,"fill":78},"144.5",[67,786,400],{"x":764,"y":787,"fill":49,"style":84,"textAnchor":314},"149.0",[776,789],{"cx":764,"cy":790,"r":779,"fill":78},"207.5",[67,792,253],{"x":764,"y":793,"fill":49,"style":84,"textAnchor":314},"212.0",[776,795],{"cx":764,"cy":796,"r":779,"fill":78},"270.5",[67,798,238],{"x":764,"y":799,"fill":49,"style":84,"textAnchor":314},"275.0",[127,801,803],{"id":802},"verification","Verification",[15,805,806,807,809,810,814],{},"Compare the container size, injected requests and main-thread time before and after on the same templates. Lab TBT should fall, and in the field, LoAF attribution should show fewer slow interactions with ",[143,808,165],{}," or vendor scripts as the top script — see ",[19,811,813],{"href":812},"\u002Fcore-web-vitals-measurement\u002Flong-animation-frames-api\u002Ffinding-slow-scripts-with-loaf-script-attribution\u002F","finding slow scripts with LoAF script attribution",". Confirm with marketing that required data still arrives.",[127,816,818],{"id":817},"worked-example-a-retail-container-with-74-tags","Worked Example: A Retail Container With 74 Tags",[15,820,821],{},"A retailer's container held 74 tags, 31 firing on all pages. The audit found 19 tags for ended campaigns, two duplicate GA configurations, a session-replay tool licensed for a pilot that had ended, and an \"All Elements\" click trigger used by a single tag. After removals, narrowing and deferral, 12 tags fired at page load. Container size dropped from 280KB to 160KB, injected third-party bytes at load fell by 540KB, lab TBT on product pages dropped by 310ms, and field INP p75 improved from 290ms to 210ms. Marketing reporting was unaffected.",[127,823,825],{"id":824},"common-mistakes","Common Mistakes",[132,827,828,834,840,848],{},[135,829,830,833],{},[138,831,832],{},"Auditing once."," Containers regrow; schedule quarterly reviews with the tag owners.",[135,835,836,839],{},[138,837,838],{},"Deferring conversion pixels."," Some tags must fire on page view for attribution; agree on the list with marketing.",[135,841,842,847],{},[138,843,844,845,384],{},"Leaving Custom HTML tags with ",[143,846,203],{}," It is blocked or slow in modern browsers; replace them.",[135,849,850,853],{},[138,851,852],{},"Testing only the homepage."," Templates differ; audit the top templates by traffic.",[127,855,857],{"id":856},"edge-cases","Edge Cases",[15,859,860,863],{},[138,861,862],{},"Server-side tagging."," Moving collection to a server container reduces client-side vendor scripts, though the web container and some tags remain. It is the most effective structural change for heavy setups.",[15,865,866,869],{},[138,867,868],{},"Consent mode."," With consent mode, tags may load but behave differently before consent; measure both pre- and post-consent states.",[15,871,872,875],{},[138,873,874],{},"Multiple containers."," Sites sometimes load two containers (agency and in-house). Each adds its own base cost; consolidate where possible.",[15,877,878,881],{},[138,879,880],{},"SPA page views."," History-change triggers can fire tags on every client-side navigation, re-running heavy tags far more often than expected.",[127,883,885],{"id":884},"faq","FAQ",[887,888,891,895],"details",{"className":889},[890],"faq-item",[892,893,894],"summary",{},"Does loading GTM async make it harmless?",[15,896,897],{},"Async prevents it from blocking HTML parsing, but its evaluation and the tags it fires still run on the main thread during load, and click triggers still run during interactions. Async addresses only one of several costs.",[887,899,901,904],{"className":900},[890],[892,902,903],{},"Can GTM run in a Web Worker with Partytown?",[15,905,906,907,911],{},"Partly. Partytown can run many tags off the main thread, but compatibility varies and some tags need synchronous DOM access. Evaluate per tag; ",[19,908,910],{"href":909},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fpartytown-vs-async-script-loading-for-tag-managers\u002F","Partytown vs async script loading for tag managers"," compares the approaches.",[887,913,915,918],{"className":914},[890],[892,916,917],{},"Who should own the container's performance?",[15,919,920],{},"Shared ownership works best: marketing owns which tags exist and why, engineering owns performance budgets and reviews additions. A simple rule — every new tag needs an owner, a removal date and a performance check — prevents most regrowth.",[887,922,924,927],{"className":923},[890],[892,925,926],{},"Is the container size itself a problem?",[15,928,929],{},"Yes, modestly: it is downloaded and parsed on every page. Removing unused tags, triggers and variables shrinks it, and each removal also removes runtime work, which matters more.",[887,931,933,936],{"className":932},[890],[892,934,935],{},"What metrics should the audit report to stakeholders?",[15,937,938],{},"Report a before-and-after table for the top templates: container size, injected third-party bytes, number of tags firing at load, lab TBT, and field INP p75. Add the list of removed tags with their former owners' sign-off. Concrete numbers and named decisions make the next audit easier to justify and harder to undo.",[127,940,942],{"id":941},"related","Related",[132,944,945,952,959],{},[135,946,947,951],{},[19,948,950],{"href":949},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fmeasuring-third-party-cost-with-the-coverage-panel\u002F","Measuring third-party cost with the Coverage panel"," — byte-level evidence for the audit.",[135,953,954,958],{},[19,955,957],{"href":956},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fmodern-module-formats-esm-vs-commonjs\u002Fdeferring-non-critical-analytics-scripts-safely\u002F","Deferring non-critical analytics scripts safely"," — the deferral patterns in depth.",[135,960,961,965],{},[19,962,964],{"href":963},"\u002Fcore-web-vitals-measurement\u002Foptimizing-first-input-delay-fid\u002Freducing-total-blocking-time-in-lighthouse\u002F","Reducing Total Blocking Time in Lighthouse"," — tracking the gain in the lab.",[967,968,970],"script",{"type":969},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Audit Google Tag Manager Container Weight\",\n  \"description\": \"A practical audit of a Google Tag Manager container — size, tags, triggers and execution cost — with fixes that protect INP and LCP.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Inventory tags with owners and purpose\",\n      \"text\": \"From the exported JSON, list every tag with its type, triggers and last-modified date.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Measure each tag's runtime cost\",\n      \"text\": \"Use preview mode with a throttled trace, or temporarily pause tags in a workspace and compare traces.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Remove, narrow and defer\",\n      \"text\": \"Expected outcome: fewer tags at load, and the remaining non-critical ones out of the startup window.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Replace interaction triggers that run on every click\",\n      \"text\": \"Swap \\\"All Elements\\\" click triggers for narrowly scoped ones (specific CSS selectors), and push explicit dataLayer events from your own code for important interactions.\"\n    }\n  ]\n}\n",[967,972,973],{"type":969},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Audit Google Tag Manager Container Weight\",\n  \"description\": \"A practical audit of a Google Tag Manager container — size, tags, triggers and execution cost — with fixes that protect INP and LCP.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight\u002F\"\n  }\n}\n",[967,975,976],{"type":969},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"JavaScript Bundle Optimization & Code Splitting\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fjavascript-bundle-optimization-code-splitting\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Third-Party Script Performance\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Auditing Google Tag Manager Container Weight\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight\u002F\"\n    }\n  ]\n}\n",[978,979,980],"style",{},"html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":334,"searchDepth":347,"depth":347,"links":982},[983,984,985,991,992,993,994,995,996],{"id":129,"depth":347,"text":130},{"id":181,"depth":347,"text":182},{"id":318,"depth":347,"text":319,"children":986},[987,988,989,990],{"id":323,"depth":368,"text":324},{"id":564,"depth":368,"text":565},{"id":571,"depth":368,"text":572},{"id":689,"depth":368,"text":690},{"id":802,"depth":347,"text":803},{"id":817,"depth":347,"text":818},{"id":824,"depth":347,"text":825},{"id":856,"depth":347,"text":857},{"id":884,"depth":347,"text":885},{"id":941,"depth":347,"text":942},"A practical audit of a Google Tag Manager container — size, tags, triggers and execution cost — with fixes that protect INP and LCP.","md",{"slug":1000,"type":1001,"breadcrumb":1002,"datePublished":1010,"dateModified":1010},"auditing-google-tag-manager-container-weight","article",[1003,1006,1007,1008],{"name":1004,"url":1005},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1009},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight\u002F","2026-10-06",true,"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight",{"title":5,"description":1014},"Measure what your GTM container and its tags cost in bytes and main-thread time, find dead and duplicate tags, and change triggers so tags stop hurting INP.","javascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fauditing-google-tag-manager-container-weight\u002Findex","zfPzZEH24l9xucEuEDLRmwCu_w1xWzPfRzAmo6j2ghg",[1018,1021],{"title":22,"path":1019,"stem":1020,"children":-1},"\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance","javascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Findex",{"title":1022,"path":1023,"stem":1024,"children":-1},"Isolating Ad Scripts from the Main Thread","\u002Fjavascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fisolating-ad-scripts-from-the-main-thread","javascript-bundle-optimization-code-splitting\u002Fthird-party-script-performance\u002Fisolating-ad-scripts-from-the-main-thread\u002Findex",1791308071607]