Lazy Loading & Smart Refresh
How Advlume lazily loads below-the-fold slots using an 800px IntersectionObserver margin, and refreshes ads every 30 seconds of viewability up to 10 times per session.
Two features work together to maximise the value of every impression on your pages: lazy loading defers auctions until an ad is genuinely about to be seen, and smart refresh runs a fresh auction each time a visitor stays in front of an ad long enough for it to matter. Both are active by default for every banner slot — there is nothing to configure.
Lazy loading
How it works
When the Advlume wrapper initialises it divides your slots into two groups:
- In-viewport slots — any slot already visible when the page loads. These are auctioned immediately.
- Out-of-viewport slots — everything below the fold. An
IntersectionObserverwatches each element and fires the auction when the slot comes within 800px of the viewport.
The 800px root margin means the auction starts while the user is still scrolling toward the slot, giving the full Prebid timeout to complete before the creative actually needs to render. By the time the slot crosses into view, the winning bid is already in GPT and the creative loads instantly.
Why this matters
- Higher viewability rates. Auctions only run for slots that are imminently visible. DSPs that pay a premium for viewable inventory see better results, which increases your CPMs over time.
- No wasted bid requests. Slots below the fold that a visitor never reaches are never auctioned, reducing unnecessary calls to demand partners.
- Faster initial page load. Running fewer network requests at page load reduces contention with above-the-fold content.
Slots that are exempt
Video slots (data-advlume-format="instream" or data-advlume-format="outstream") are not subject to lazy loading. They follow their own load triggers managed by the video player.
Smart refresh
How it works
Once an ad has rendered, the wrapper starts a viewability timer for that slot. The timer only runs while at least 50% of the slot is in the viewport. If the visitor scrolls the slot away before the timer fires, the timer pauses and resets when the slot comes back into view.
| Parameter | Value |
|---|---|
| Viewability threshold | 50% of slot in viewport |
| Refresh interval | 30 seconds of continuous viewability |
| Maximum refreshes per slot per session | 10 |
| Min hidden time before refresh on tab return | 5 seconds |
On each refresh the wrapper:
- Clears all
hb_*targeting keys from the GPT slot so stale Prebid data does not bleed into the new auction. - Sets an
advlume_rc(refresh count) targeting key so you can track refresh impressions separately in reporting if needed. - Runs a full new Prebid auction against all active bidders.
- Calls
googletag.pubads().refresh()with the new targeting in place.
Tab visibility handling
When a visitor switches to another browser tab the wrapper detects the visibilitychange event and immediately pauses all running refresh timers. While the tab is hidden it also runs a prefetch auction in the background, so fresh bids are ready the moment the visitor returns.
When the tab becomes visible again the wrapper checks how long it was hidden:
- Less than 5 seconds — the session is considered uninterrupted. Timers resume and no re-auction happens (avoiding a double auction on a brief Alt-Tab).
- 5 seconds or more — a compare auction runs for every slot near the viewport. The prefetched bids from when the tab was hidden are used, so the new creative renders with minimal delay.
Failsafe refresh
3,000ms after slots are initially displayed, the wrapper runs a failsafe sweep: any slot that is in the viewport but has no rendered iframe is force-refreshed. This recovers impressions lost to GPT race conditions or slow creative loading, and counts toward the slot's refresh total.
Why CPMs improve with refresh
Each refresh is a fresh open auction. The winning price on refresh impressions is often higher than on initial load because:
- The user has demonstrated engagement by staying on the page.
- The browser context (scroll depth, time on page) is richer, which some DSPs use for better targeting.
- Refresh inventory is explicitly signalled via
advlume_rc > 0, which some demand partners bid more aggressively on.
The 10-refresh cap prevents runaway auction loops on very long sessions and keeps overall request volume within IAB guidelines.
Further reading
- How Ads Are Served — the full impression lifecycle that lazy loading and refresh plug into
- Layout Shift (CLS) Issues — how to pre-reserve slot height to prevent content jumping when ads load
- Key Metrics Explained — viewability rate and how it affects CPMs
Last updated 2 months ago