Last active
February 21, 2022 18:15
-
-
Save davewalker235/e090c19cef62206b14a0fe2677168515 to your computer and use it in GitHub Desktop.
Lazyload Google DFP ads with SRA Roadblock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script async="async" src="https://www.googletagservices.com/tag/js/gpt.js"></script> | |
<script> | |
// This is a very basic example of Lazyloading DFP ads with an SRA roadblock. | |
// The example uses ES2016 javascript syntax and relies on | |
// IntersectionObservers. Normally in production this would be transpiled | |
// with babel and polyfilled for support. It also relies on DFP maintaining a | |
// changeCorrelator for all ad requests. Historically this correlator has | |
// timed out after 30 seconds, which is why this example relies on a js timer | |
// to force loading after 25 seconds. Our sites have been using a version of | |
// this code in production since late 2017, the method has been observed to | |
// be stable and validated by our DFP rep. Depending on your account the | |
// correlator may no longer time out and you might not need to use this | |
// method, you should consult the following article before settling on this | |
// method. | |
// See release notes for October 29th, 2018. The feature is referred to as | |
// "long-lived page views": | |
// https://support.google.com/admanager/answer/7636572 | |
// Set up the googletag object to push cmds and slots onto array stacks | |
// for proper async handling | |
window.googletag = window.googletag || {}; | |
window.googletag.cmd = window.googletag.cmd || []; | |
window.googletag.empty_slots = window.googletag.empty_slots || []; | |
window.googletag.cmd.push(() => { | |
// Set up page for SRA and disable auto loading of ads | |
window.googletag.pubads().enableSingleRequest(); | |
window.googletag.pubads().disableInitialLoad(); | |
window.googletag.enableServices(); | |
// The empty slots attribute will hold any ad slots that haven't been | |
// loaded by the IntersectionObserver. DFPs changeCorrelator historically | |
// times out after 30 seconds. We refresh any empty slots after 25 seconds | |
// to ensure they use the same SRA request | |
setTimeout(() => { | |
window.googletag.my_observer.disconnect(); | |
if (window.googletag.empty_slots) { | |
window.googletag.pubads() | |
.refresh(window.googletag.empty_slots, {changeCorrelator: false}); | |
} | |
}, 25000); | |
}); | |
</script> | |
<style> | |
.gdfp { | |
background: #CCC; | |
margin-bottom: 150vh; | |
width: 250px; | |
height: 250px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="gdfp"></div> | |
<div class="gdfp"></div> | |
<div class="gdfp"></div> | |
</body> | |
<script> | |
// Create an observer that will load any ad within 150px of the viewport. | |
// Observer is assigned to the global googletag object so it can be cleared | |
// after the 30 second window has passed | |
window.googletag.my_observer = new IntersectionObserver((items) => { | |
items.forEach(i => { | |
// Loop through possible elements to find the one currently intersecting | |
if (!i.isIntersecting) return; | |
// Stop watching this element | |
window.googletag.my_observer.unobserve(i.target); | |
// Push a function onto the cmd stack to remove this ad slot from our | |
// cache list and load the ad with the frozen changeCorrelator | |
window.googletag.cmd.push(() => { | |
let n = i.target.getAttribute('data-gdfp-slot'); | |
let i = window.googletag.empty_slots.indexOf(slot); | |
let slot = window.googletag.pubads().getSlots()[n]; | |
window.googletag.empty_slots.splice(i, 1) | |
window.googletag.pubads().refresh([slot], { changeCorrelator: false }); | |
}); | |
}); | |
}, { rootMargin: '150px' }); | |
window.googletag.cmd.push(() => { | |
let ads = document.querySelectorAll('.gdfp'); | |
ads.forEach((i, n) => { | |
i.setAttribute('id', 'gdfp_' + n); | |
i.setAttribute('data-gdfp-slot', n); | |
let slot = window.googletag | |
.defineSlot('/dfpid/slot', [300, 250], i.id) | |
.addService(window.googletag.pubads()); | |
// Push the slot onto the empty_slots array, will be removed as it is | |
// loaded. Call display to activate slot and observe with observer | |
window.googletag.empty_slots.push(slot); | |
window.googletag.display(i.id); | |
window.googletag.my_observer.observe(i); | |
}); | |
}); | |
</script> | |
</html> |
Hi Matt, I just updated the gist with the best link I could find for the release notes, please see above for a description of where to find the information.
Hi Dave, thanks for sharing this. Now, GPT supports ad lazy load. Does your solution have any advantages over the official one? https://developers.google.com/publisher-tag/samples/lazy-loading
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am investigating how to support both ad refreshing and roadblocked ads, so thank you for this...I'm trying to determine if this is an appropriate solution for our site, and I went to the link you provided (https://support.google.com/admanager/answer/179039?hl=en) but that link just points to the most recent release notes for ad manager (which currently is the January 28, 2019 release). Which release notes were you actually linking to originally? Thanks