Taming the Speed Impact of Third-Party Tags Andy Davies · May 2023 · #WeLoveSpeed @AndyDavies Photo by Jonas Koel on Unsplash

fl @AndyDavies https://www. ickr.com/photos/dharmabum1964/3108166405

Compete for the Network @AndyDavies

Compete for the Network @AndyDavies

Make us wait for new connections @AndyDavies

Fight for the Main Thread @AndyDavies

Fight for the Main Thread Before After @AndyDavies

They may provide important features too: Advertising Analytics Content Error Reporting Experimentation and Testing Personalisation Real User Monitoring Revenue Attribution Reviews Session Replay User Generated Content @AndyDavies and much, much more…

How do we nd the balance between… …their bene ts and their challenges? @AndyDavies https://unsplash.com/photos/rBLTWS3WsQ8

What’s on your page and where is it from? @AndyDavies https://requestmap.herokuapp.com

Some key questions… Are we still paying for it? Does anyone still use it? Are there any duplicates? For static content, can we replace it with a locally hosted version? What’s the tag’s impact on the visitor’s experience? When should we load it? Where should it be executed? @AndyDavies

May not be easy for Ad funded sites @AndyDavies https://requestmap.herokuapp.com

If page load is a journey… @AndyDavies

If page load is a journey… ??? @AndyDavies ??? ??? ??? ??? ??? …where do our third-parties t in?

Early tags can have a Critical Impact Often parser or render blocking Compete for main thread even when loaded async Typical tags Tag Managers Experimentation Personalisation @AndyDavies

Avoid Render Blocking 3rd-Parties

<link rel=”stylesheet” href=”some-3rd-party.example.com/styles.css” /> <script src=”some-3rd-party.example.com/script.js”></script> @AndyDavies

Often focus on blocking requests failing… @AndyDavies

Often focus on blocking requests failing… @AndyDavies

But what happens when they succeed? @AndyDavies

Preconnect won’t save us… (And neither will early hints in this example) @AndyDavies

Might not be able to use it anyway…

<link rel=”preconnect” href=”third-party-origin.example.com”> @AndyDavies

Might not be able to use it anyway…

<link rel=”preconnect” href=”third-party-origin.example.com”> Discloses the visitor’s IP address to the 3rd-party Did you ask for the visitor’s consent rst? fi @AndyDavies

fi https://www.theregister.com/2022/01/31/website_ ne_google_fonts_gdpr/

If Google Fonts isn’t considered ‘legitimate usage’ Then surely static content from other third-party hosts isn’t either* * and I think that’s a good thing @AndyDavies

https://csswizardry.com/2019/05/self-host-your-static-assets/

I Am Not a Lawyer nor a Data Protection O cer ffi @AndyDavies

I Am Not a Lawyer You nor should a talk to yours Data Protection O cer ffi @AndyDavies

Need Consent before loading 3rd-Parties fl @AndyDavies https://www. ickr.com/photos/88709139@N08/21134399326

And some CMPs are faster than others @AndyDavies

An ideal candidate for edge compute? fl @AndyDavies https://www. ickr.com/photos/kewl/8475764430

fl https://blog.cloud are.com/consent-manager/

Or should consent management be built into browsers? @AndyDavies

Consent brings other challenges too @AndyDavies

https://www.fastly.com/blog/taming-third-parties-with-a-single-origin-website

Cookies and Headers need to be ltered fl @AndyDavies https://www. ickr.com/photos/neuski/1486170673

There may still be di cult choices to make @AndyDavies https://www.flickr.com/photos/dno1967b/8347363864

Is a render blocking AB testing script worse than an anti- icker snippet? @AndyDavies

Is a render blocking AB testing script worse than an anti- icker snippet? And how does consent fit into the puzzle? @AndyDavies

Self Hosting may help but requires work https://man.gl/casper-self-host-optimizely

Other tags can wait until page is ‘complete’ Is there any point in services such as ▪︎ Chat ▪︎ Session Replay ▪︎ User feedback if our visitor is still waiting for the page to load? @AndyDavies

Watch for TTI / firstCPUIdle changes Delaying scripts will also delay any long tasks they generate Connection Setup Script Fetch Long Task Load @AndyDavies

Watch for TTI / firstCPUIdle changes Delaying scripts may also bring load forward and compensate Connection Setup Script Fetch Long Task Load @AndyDavies

Injecting preconnects can help For example inject a preconnect at DCL for a late loaded script Connection Setup DCL @AndyDavies Script Fetch Long Task Load

Tag Managers can help schedule loading @AndyDavies

Could a tag be loaded on interaction? fl @AndyDavies https://www. ickr.com/photos/joeyz51/50226695988

https://calibreapp.com/blog/fast-live-chat

https://github.com/paulirish/lite-youtube-embed

https://antonioufano.com/articles/improve-web-performance-lazy-loading-recaptcha/

https://antonioufano.com/articles/improve-web-performance-lazy-loading-recaptcha/

fl @AndyDavies https://www. ickr.com/photos/pherk/4492973614

The ‘Messy Middle’ This is a fuzzy area… Does the tag provide user content? How much data loss are you willing allow? Try not to block the browser Server-Side Tagging helps @AndyDavies

Example From a newspaper I worked with in early 2021 @AndyDavies

Prioritise by Importance and Urgency Delaying less important content stops it competing for network and device resources with more important content Start of Page Load End of Page Load Prioritise important and urgent content (from both visitor and commercial perspectives) Less important and less urgent content should be loaded later Time @AndyDavies

Categorise into strategic buckets Start of Page Load Core Content End of Page Load Consent Management Primary Partners Secondary Partners Time (not to scale) @AndyDavies Secondary Content Leftovers

How existing content ts this strategy There will be some blurring of the boundaries between the buckets, and some challenges e.g. JW Player waits for Permutive, it’s also possible to defer some content until visitor scrolls. Shrinking content size (both core and partner) is still important too. Start of Page Load Newspaper End of Page Load GPT Taboola AMP Prebid PolarMedia JW Player Permutive Core Content Quantcast Consent Management Primary Partners Recaptcha SailThru Airship Secondary Partners Time (not to scale) @AndyDavies ViaFoura Secondary Content Leftovers

Where should a tag be executed? fl @AndyDavies https://www. ickr.com/photos/hugosimmelink/2673580935

Generally, tags execute on the main thread But there are some interesting alternatives @AndyDavies

Server-Side Tagging = Less Tags & Beacons Own Hosting GTM Container @AndyDavies Server-Side Container

What about executing on the Edge? fl @AndyDavies https://www. ickr.com/photos/johann-in-london/92533884

https://github.com/WICG/proposals/issues/54

We can execute tags in workers too https://partytown.builder.io/ @AndyDavies

A multitude of options to consider! Server Side Edge Worker Main Thread @AndyDavies Response Start FCP CMP Load Tag Manager Load DCL Page Load Interaction

fl @AndyDavies https://www. ickr.com/photos/nikkvalentine/16077068743

Monitor third-party performance @AndyDavies

Measure with and without Consent Requests Size (KB) @AndyDavies 41 + 55 589 + 1280 41 + 128 589 + 1750

And maybe even without 3rd-Parties? Requests Size (KB) @AndyDavies 41 + 11 589 + 246 41 + 55 589 + 1280 41 + 128 589 + 1750

Track Tag Container Releases @AndyDavies

Track Tag Container Releases GTM only supports email noti cations 😞 fi @AndyDavies

GitHub Actions to the Rescue! 1. Check out repo 2. Fetch GTM Container(s) 3. Reformat 4. Extract version number 5. If version has changed… call SpeedCurve API 6. Check changed les in fi @AndyDavies

https://github.com/andydavies/gtm-watcher

V fl fl https://www. ickr.com/photos/shoesmiths/5427623567 https://www. ickr.com/photos/wwarby/7109538317

How long is an anti- icker snippet active? (function (node, selector, name) { performance.mark(name + ‘-start’); const callback = function (mutationsList, observer) { // Use traditional ‘for loops’ for IE 11 support for (const mutation of mutationsList) { if (mutation.attributeName === ‘class’ && !mutation.target.classList.contains(selector) && mutation.oldValue.includes(selector)) { performance.mark(name + ‘-end’); performance.measure(name + ‘-duration’, name + ‘-start’, name + ‘-end’); observer.disconnect(); break; } } } const observer = new MutationObserver(callback); observer.observe(node, { attributes: true, attributeOldValue: true }); @AndyDavies })(document.documentElement, ‘async-hide’, ‘anti-flicker’);

When is an IAB EU CMP Ready? // Creates User Timing marks for cmpuishown, useractioncomplete & tcloaded if (typeof window.__tcfapi === ‘function’) { window.__tcfapi(‘addEventListener’, 2, (tcdata, success) => { if(success) { performance.mark(‘tcf-’ + tcdata.eventStatus); // Stop listening after TCF loaded, or user action complete to prevent generation // of extra cpuishown & useractioncomplete marks if visitor reopens CMP UI if(tcdata.eventStatus === ‘useractioncomplete’ || tcdata.eventStatus === ‘tcloaded’) { window.__tcfapi(‘removeEventListener’, 2, (success) => { }, tcdata.tcfListenerId); } } }); } @AndyDavies

When did a GPT creative load? var googletag = googletag || {}; googletag.cmd = googletag.cmd || []; googletag.cmd.push(function() { // This listener will be called when the creative’s iframe onload event fires googletag.pubads().addEventListener(‘slotOnload’, function(event) { performance.mark(‘adslot-’ + event.slot.getSlotElementId() + ‘-loaded’); }); }); @AndyDavies

https://github.com/andydavies/tag-timing-snippets

fl @AndyDavies https://www. ickr.com/photos/brisbanecitycouncil

https://github.com/w3c/longtasks/blob/main/loaf-explainer.md

Let’s return to our 3rd-Party Puzzle fl @AndyDavies https://www. ickr.com/photos/mattyp/4173076669

Before After @AndyDavies

Pro le the page @AndyDavies

Read the Source… @AndyDavies

@AndyDavies

https://github.com/krux/postscribe/

https://github.com/krux/postscribe/

Postscribe is only included if this box is checked @AndyDavies

It’s only needed when document.write is used in this eld* Postscribe is only included if this box is checked

  • not needed if snippet uses document.open, document.write, document.close sequence fi @AndyDavies

Find “vtp_supportDocumentWrite”:\s?true, @AndyDavies

Find “vtp_supportDocumentWrite”:\s?true, @AndyDavies

Find “vtp_supportDocumentWrite”:\s?true, @AndyDavies

Find “vtp_supportDocumentWrite”:\s?true, @AndyDavies

Postscribe removed from George Clothing @AndyDavies https://mobile.twitter.com/rnebhwani/status/1376514746107752452

What other secrets does GTM hold? fl @AndyDavies https://www. ickr.com/photos/david44149/49811626782

Add log points for DOM operations @AndyDavies

Add log points for DOM operations @AndyDavies

@AndyDavies

@AndyDavies

@AndyDavies

@AndyDavies

Some other things we discovered… ▪︎ When Google Optimize is enabled it adds another copy of Analytics (even if you don’t actively use Optimize) ▪︎ Custom Google Analytics dimensions can be expensive when set from GTM (we removed unused ones) ▪︎ Other miscellaneous cleanups I suspect we just ‘scratched the surface and there was other gains to nd fi @AndyDavies

Before After @AndyDavies

3rd Party Tags can make or break your visitor experience Make friends with the team that manages your tags Audit tags – remove the ones that aren’t needed Don’t accept the defaults – choreograph tag loading Push the boundaries beyond the browsers main thread Chase 3rd-Parties to x their issues Share what you learn fi @AndyDavies

https://www.tunetheweb.com/blog/adding-controls-to-google-tag-manager/

https://man.gl/telegraph-3rd-party-performance

Taming Tags improves user experience @AndyDavies

It can also deliver nancial bene ts Median Page Load Time (s) 14 Android iOS 26% increase in revenue from Android visitors 12 10 8 6 4 2 0 ee W ee W ee W ee W ee W ee W k k k k k k 5 5 3 2 1 0 @AndyDavies

Thanks! @AndyDavies andy.davies@speedcurve.com https://noti.st/andydavies/ib1Hpp/reducing-the-speed-impactof-third-party-tags