Help improve the Google Publisher Tag developer experience. Share your thoughts in our survey.

Lazy loading

Lazy loading enables pages to load faster, reduces resource consumption and contention, and improves viewability rate by pausing the requesting and rendering of ads until they approach the user's viewport.

With lazy loading in SRA, when the first ad slot comes within the viewport specified by the fetchMarginPercent parameter, the call for that ad and all other ad slots is made.

Sample implementation

<!doctype html>
<!--
 Copyright 2020 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<html>
  <head>
    <meta charset="utf-8">
    <title>Lazy loading example</title>
    <script async src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
    <script>
      window.googletag = window.googletag || {cmd: []};

      googletag.cmd.push(function() {
        googletag.defineSlot('/6355419/Travel', [728, 90], 'div-1')
          .setTargeting('test', 'lazyload')
          .addService(googletag.pubads());
        googletag.defineSlot('/6355419/Travel', [728, 90], 'div-2')
          .setTargeting('test', 'lazyload')
          .addService(googletag.pubads());
        googletag.defineSlot('/6355419/Travel', [728, 90], 'div-3')
          .setTargeting('test', 'lazyload')
          .addService(googletag.pubads());

        // Some examples of ways to enable lazy loading below.
        // Normally, only one of these methods should be used.

        // A) Enable with defaults.
        googletag.pubads().enableLazyLoad();

        // B) Enable without lazy fetching. Additional calls override previous
        // ones.
        googletag.pubads().enableLazyLoad({fetchMarginPercent: -1});

        // C) Enable lazy loading with...
        googletag.pubads().enableLazyLoad({
          // Fetch slots within 5 viewports.
          fetchMarginPercent: 500,
          // Render slots within 2 viewports.
          renderMarginPercent: 200,
          // Double the above values on mobile, where viewports are smaller
          // and users tend to scroll faster.
          mobileScaling: 2.0
        });

        // Register event handlers to observe lazy loading behavior.
        googletag.pubads().addEventListener('slotRequested', function(event) {
          updateSlotStatus(event.slot.getSlotElementId(), 'fetched');
        });

        googletag.pubads().addEventListener('slotOnload', function(event) {
          updateSlotStatus(event.slot.getSlotElementId(), 'rendered');
        });

        googletag.enableServices();
      });

      function updateSlotStatus(slotId, state) {
        var elem = document.getElementById(slotId + '-' + state);
        elem.className = 'activated';
        elem.innerText = 'Yes';
      }
    </script>
    <style>
      div.ad-slot {
        border-style: dashed;
        display: block;
        margin: auto;
      }

      div.main-content {
        background-color: lightsteelblue;
        margin-top: 125px;
        overflow: hidden;
        width: 100%;
      }

      div.status-panel {
        background: white;
        height: 125px;
        position: fixed;
        top: 0;
        width: 100%;
      }

      table {
        width: 100%;
      }

      table th {
        text-align: center;
      }

      table td:not(.slot-name) {
        background-color: lightsalmon;
      }

      table td.activated {
        background-color: lightgreen;
      }
    </style>
  </head>
  <body>

    <!--
       As defined by lazy load settings, initially:
       1. Slot 1 will be fetched and rendered on mobile and desktop.
       2. Slot 2 will be fetched on mobile and desktop, but will not be rendered on desktop.
       3. Slot 3 will not be fetched or rendered on mobile or desktop.
    -->

    <div class="main-content">
      <div id="div-1" class="ad-slot" style="height: 90px; width: 728px;">
        <script>
          googletag.cmd.push(function() { googletag.display('div-1'); });
        </script>
      </div>

      <!-- 3 viewport tall div to place next slot 3 viewports away. -->
      <div style="height:300vh"></div>

      <div id="div-2" class="ad-slot" style="height: 90px; width: 728px;">
        <script>
          googletag.cmd.push(function() { googletag.display('div-2'); });
        </script>
      </div>

      <!-- 9 viewport tall div to place next slot 12 viewports away. -->
      <div style="height:900vh"></div>

      <div id="div-3" class="ad-slot" style="height: 90px; width: 728px;">
        <script>
          googletag.cmd.push(function() { googletag.display('div-3'); });
        </script>
      </div>
    </div>

    <div class="status-panel">
      <table>
        <tr>
          <th>Ad Slot</th>
          <th>Fetched?</th>
          <th>Rendered?</th>
        </tr>
        <tr>
          <td class="slot-name">Ad Slot 1</td>
          <td id="div-1-fetched">No</td>
          <td id="div-1-rendered">No</td>
        </tr>
        <tr>
          <td class="slot-name">Ad Slot 2</td>
          <td id="div-2-fetched">No</td>
          <td id="div-2-rendered">No</td>
        </tr>
        <tr>
          <td class="slot-name">Ad Slot 3</td>
          <td id="div-3-fetched">No</td>
          <td id="div-3-rendered">No</td>
        </tr>
      </table>
      <p>
        Scroll the container below to lazily load the ad slots.
      </p>
    </div>
  </body>
</html>