The GNI Ad Revenue Lab identified the most straightforward tactics to boost viewability and overall revenue for publishers of all sizes.
Ad networks assign value to inventory based on two pairs of variables: site content and user demographics, and then inventory viewability and volume. Machine learning is used to either follow a user around the web via cookies (called remarketing), or target new users via a specific set of requirements created by the advertiser (i.e. users visiting a travel site). Depending on how closely aligned your audience and site is with an advertiser’s targeting requirements, and how viewable your ads are, programmatic CPMs have an opportunity to be as high, if not higher than your direct sold campaigns.
Viewability has become a major theme in this accelerator as many publishers still live and die by impression count alone. As technology has evolved, advertisers have become more aware of ways to measure ad performance and ROI of their ad spend. When it comes to optimizing programmatic revenue, viewability is key.
When using Google Publisher Tags (GPT) GPT, one of the quickest ways to ensure optimal viewability is to lazy load all ad units that aren’t in view on initial load, i.e. waiting to fetch and render each ad unit until it’s about to come into view for the user.
Within the GPT code in the head, adding the following three lines just before googletag.enableServices(); enables lazy loading for all ad units. The values of the fetch and render margins are the minimum distance from the viewport that an ad slot must be. For example, a value of 100 would require the ad slot be one viewport away, 300 is three viewports away. We saw the best results for viewability when both the fetch and render margins were set to 0, or as the ad slot enters the viewport.
googletag.pubads().enableLazyLoad({
fetchMarginPercent: 0, // When the slot enters the viewport.
renderMarginPercent: 0, // When the slot enters the viewport.
});
It’s important to note that initial implementation of lazy loading will cause a drop in impressions, as all ad units will no longer have an impression counted upon initial page load. However, in Long Beach Post’s case, Ad Manager’s Ad Exchange was enabled at the same time lazy loading was implemented. This allowed Ad Manager to start filling the large amount of unfilled impressions, causing an increase in impressions, rather than the decrease we typically see from lazy loading.
Though in the case of initial loss from impression from lazy loading, there are two ways to recover: improve CPMs and increase impressions. For Long Beach Post, we knew we’d see an increase in CPM due to the improved viewability, so the next play was to increase impressions without adding more ad units on the page.
To capitalize on the current ad units that now have high viewability due to lazy loading, we leveraged our most engaged users by using time on page to trigger a time-based “active-view” slot refresh — meaning the ad unit maintained viewability. The slot is only refreshed when all of the following rules are true:
- at least 70% of the ad unit must be within the viewport,
- the user’s tab must be active,
- if the unit exits the viewport and then re-enters as the user scrolls, the timer must restart.
Rather than build this functionality into LBP’s WordPress theme, 10up worked with Google to build a WordPress plugin focused on optimizing the viewability of ads.
The plugin includes the previously mentioned active-view refresh functionality as well as a customizable time field so that users can easily adjust the logic to meet the behavior of their users (minimum 30 seconds). We also identified the need to disable the refresh on a per unit basis should a specific advertiser ID be detected on the creative. This last option is useful in the case that you choose not to allow a refresh to take place when a direct sold ad wins an impression, only programmatic.
After implementing both recommended viewability improvements of lazy loading and active-view refresh on Long Beach Post, we saw a steady increase in fill of remaining inventory, paying an average of $1.45 CPM. When you multiply this by the unfilled impressions and the increase in traffic we achieved through other strategies, it added up to $4,250 in additional revenue during October of 2019, and continues to be a steady source of “passive” revenue for Long Beach Post.

Case Study | GNI Publishers
65%
Increase in Viewability
The Cost of Calling But Not Rendering
With Google Publisher Tags (GPT) specifically, if an ad unit is defined in the head, but not called in the body, the call is still sent to Ad Manager and a creative is returned, but never rendered. On the programmatic front, this negatively impacts viewability, which then negatively affects CPMs. On the direct side, this causes a “false” impression to be reported.
On Long Beach Post, there was an implementation issue that prevented the creative from rendering on the frontend — the div was being hidden with CSS. This caused the average programmatic CPM for that unit to drop at a rate correlated to its drop in viewability.
There are several ways this type of issue can be remediated: size mapping for units specific to certain screen sizes, or defining units based on template for units specific to different page layouts. For the issue mentioned above, size mapping was the fix. The intention was for the unit to be displayed on mobile devices only, or screens less than 350 pixels wide. This allows the unit to still be defined in the head on larger breakpoints, but prevents the call to Ad Manager from being made unless the user is on a smaller device. Ensuring that the ad unit was only called when it was intended to be displayed caused viewability to increase from 46% to 87% (for this specific ad unit).
Helpful Resources:
• Google’s Viewability Best Practices
• Lazy Loading Developer Guide
• Understanding Viewability and Active View Reporting Metrics
• How Active View Measures Viewability