Reducing the Speed Impact of Third-Party Tags

A presentation at Performance.Now in October 2022 in Amsterdam, Netherlands by Andy Davies

Slide 1

Slide 1

Reducing the Impact of Third-Party Tags Andy Davies · Oct 2022 · #PerfNow @AndyDavies https://www.flickr.com/photos/digitizedchaos/3964206549

Slide 2

Slide 2

@AndyDavies https://www.flickr.com/photos/dharmabum1964/3108166405

Slide 3

Slide 3

Compete for the Network @AndyDavies

Slide 4

Slide 4

Compete for the Network @AndyDavies

Slide 5

Slide 5

Make us wait for new connections @AndyDavies

Slide 6

Slide 6

Fight for the Main Thread @AndyDavies

Slide 7

Slide 7

Fight for the Main Thread Before After @AndyDavies

Slide 8

Slide 8

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…

Slide 9

Slide 9

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

Slide 10

Slide 10

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

Slide 11

Slide 11

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

Slide 12

Slide 12

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

Slide 13

Slide 13

If page load is a journey… @AndyDavies

Slide 14

Slide 14

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

Slide 15

Slide 15

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

Slide 16

Slide 16

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

Slide 17

Slide 17

Often focus on blocking requests failing… @AndyDavies

Slide 18

Slide 18

Often focus on blocking requests failing… @AndyDavies

Slide 19

Slide 19

But what happens when they succeed? @AndyDavies

Slide 20

Slide 20

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

Slide 21

Slide 21

Might not be able to use it anyway…

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

Slide 22

Slide 22

Might not be able to use it anyway…

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

Slide 23

Slide 23

https://www.theregister.com/2022/01/31/website_fine_google_fonts_gdpr/

Slide 24

Slide 24

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

Slide 25

Slide 25

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

Slide 26

Slide 26

I Am Not a Lawyer nor a Data Protection Officer @AndyDavies

Slide 27

Slide 27

I Am Not a Lawyer You nor should a talk to yours Data Protection Officer @AndyDavies

Slide 28

Slide 28

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

Slide 29

Slide 29

And some CMPs are faster than others @AndyDavies

Slide 30

Slide 30

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

Slide 31

Slide 31

Or should consent management be built into browsers? @AndyDavies

Slide 32

Slide 32

Consent brings other challenges too @AndyDavies

Slide 33

Slide 33

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

Slide 34

Slide 34

Cookies and Headers need to be filtered @AndyDavies https://www.flickr.com/photos/neuski/1486170673

Slide 35

Slide 35

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

Slide 36

Slide 36

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

Slide 37

Slide 37

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

Slide 38

Slide 38

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

Slide 39

Slide 39

Other tags can wait until page is ‘complete’ What’s the point in loading interactive elements such as ▪︎ Chat ▪︎ Session Replay ▪︎ User feedback if our visitor is still waiting for the page to load? @AndyDavies

Slide 40

Slide 40

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

Slide 41

Slide 41

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

Slide 42

Slide 42

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

Slide 43

Slide 43

Tag Managers can help schedule loading @AndyDavies

Slide 44

Slide 44

Could the tag be loaded on interaction? @AndyDavies https://www.flickr.com/photos/joeyz51/50226695988

Slide 45

Slide 45

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

Slide 46

Slide 46

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

Slide 47

Slide 47

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

Slide 48

Slide 48

@AndyDavies https://www.flickr.com/photos/pherk/4492973614

Slide 49

Slide 49

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

Slide 50

Slide 50

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

Slide 51

Slide 51

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

Slide 52

Slide 52

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

Slide 53

Slide 53

How existing content fits 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

Slide 54

Slide 54

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

Slide 55

Slide 55

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

Slide 56

Slide 56

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

Slide 57

Slide 57

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

Slide 58

Slide 58

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

Slide 59

Slide 59

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

Slide 60

Slide 60

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

Slide 61

Slide 61

@AndyDavies https://www.flickr.com/photos/nikkvalentine/16077068743

Slide 62

Slide 62

Monitor third-party performance @AndyDavies

Slide 63

Slide 63

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

Slide 64

Slide 64

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

Slide 65

Slide 65

Track Tag Container Releases @AndyDavies

Slide 66

Slide 66

Track Tag Container Releases GTM only supports email notifications ! @AndyDavies

Slide 67

Slide 67

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

Slide 68

Slide 68

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

Slide 69

Slide 69

How long is an anti-flicker 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’);

Slide 70

Slide 70

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

Slide 71

Slide 71

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

Slide 72

Slide 72

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

Slide 73

Slide 73

@AndyDavies https://www.flickr.com/photos/brisbanecitycouncil

Slide 74

Slide 74

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

Slide 75

Slide 75

Before After @AndyDavies

Slide 76

Slide 76

Profile the page @AndyDavies

Slide 77

Slide 77

Read the Source… @AndyDavies

Slide 78

Slide 78

@AndyDavies

Slide 79

Slide 79

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

Slide 80

Slide 80

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

Slide 81

Slide 81

Postscribe is only included if this box is checked @AndyDavies

Slide 82

Slide 82

And only needed if the tag uses document.write* Postscribe is only included if this box is checked @AndyDavies

  • not needed if page uses document.open, document.write, document.close sequence

Slide 83

Slide 83

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

Slide 84

Slide 84

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

Slide 85

Slide 85

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

Slide 86

Slide 86

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

Slide 87

Slide 87

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

Slide 88

Slide 88

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

Slide 89

Slide 89

Add log points for DOM operations @AndyDavies

Slide 90

Slide 90

Add log points for DOM operations @AndyDavies

Slide 91

Slide 91

@AndyDavies

Slide 92

Slide 92

@AndyDavies

Slide 93

Slide 93

@AndyDavies

Slide 94

Slide 94

@AndyDavies

Slide 95

Slide 95

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 find @AndyDavies

Slide 96

Slide 96

Before After @AndyDavies

Slide 97

Slide 97

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 fix their issues @AndyDavies

Slide 98

Slide 98

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

Slide 99

Slide 99

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

Slide 100

Slide 100

Taming Tags improves user experience @AndyDavies

Slide 101

Slide 101

It can also deliver financial benefits 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

Slide 102

Slide 102

Thanks! @AndyDavies hello@andydavies.me