Optimizing DFP performance

September 11th, 2010 | by Sajal Kayan |

Ive been using DFP (DoubleClick for Publishers – formerly Google Ad Manager) to serve ads as it has some certain features I really need.

The downside of using DFP is that its browser side performance sucks big time. On my site, I use the experimental Iframe tagging, which basically writes an iframe in place of the ad and loads the third party ad codes into it. This runs asynchronously and is nice, but the DFP’s bootstrap javascript blocks rendering and it needs to load 3 javascript files from Google serially. This bootstrap must be available before trying to fill an ad slot.

The Goal

Show the story title and body to the user As Soon As Possible

The Problem

The instructions of implementing the Iframe tagging is as such.

In the <head>…</head> section :-


<!-- PUT THIS TAG IN THE head SECTION -->
<script src="http://partner.googleadservices.com/gampad/google_service.js" type="text/javascript"></script>
<script type="text/javascript">
GS_googleAddAdSenseService("ca-pub-xxxxxxxxxxxxxxxx");
GS_googleEnableAllServices();
</script>
<script type="text/javascript">
GA_googleUseIframeRendering();
</script>
<!-- END OF TAG FOR head SECTION -->

And where the ad slot needs to be displayed always in the <body>…</body>:-


<script type="text/javascript">
GA_googleFillSlotWithSize("ca-pub-xxxxxxxxxxxxxxxx", "slot_name", 728, 90);
</script>

The resulting waterfall chart of this method :-

DFP before

Requests #3, #4 and #5 is the bootstrap for DFP. The green line indicates the first paint event.

It is clear that

  1. The browser needs to make 3 sequential requests
  2. Until these 3 javascripts are downloaded and parsed, the rendering cannot begin. – The user is affectively staring at a blank screen.
  3. The browser is doing nothing else while downloading these files.

The Workaround

I was going to mark this section as a “solution” to the problem… but it isint. The page is still susceptible to frontend SPOF .. That is if the servers hosting the DFP JavaScripts is unaccessible, that calls for a terrible user experience on my site.

What I did was simply moved the bootstrap to just before the first time the GA_googleFillSlotWithSize() function was called. i.e. move the bootstrap from the <head> to the <body> part of the page.

The waterfall chart for this is :-

DFP after

Requests #3, #7 and #8 is the bootstrap for DFP. The green line indicates the first paint event.

It is clear that

  1. The browser still needs to make 3 sequential requests
  2. While the bootstrap was loading, the user can see the header of the site, providing visual feedback that something is happening. – The start render did not have to wait.
  3. The browser is downloading images, etc referred to earlier while downloading the bootstrap.
  4. There is 200ms improvement in the time at which the user can start reading the story.

Here is a video comparing the 2 loading methods :-

If anyone has better ways to embed DFP, please let me know via comments below.

The Solutions

There are 2 ways to solve this

  • Have source ordered HTML where the adcodes are always after the content in the HTML source of the page. This ensures that the user can start reading while DFP does its blocking thing. – A site redesign is in planning and that would implement this step.
  • DFP changes the way it works… by replacing the evil document.write with DOM manipulation techniques so the scripts can be loaded asynchronously.

So next time if a third party script provider tells you that certain code must be in the <head> of the HTML, don’t believe them and question them.

PS: All tests were done from ie7 from Dulles, VA using WebPageTest.org, ie8 also showed similar behavior.

Shameless Plug

I am available for consulting on web speed issues, contact details in the right sidebar.

UPDATE: I am now using Aaron’s adsense hack to defer DFP below the content. Thanks Aaron
UPDATE 2: New Post: Complete Asynchronous ad loading using DFP and LABjs

  • http://www.iyinetfrmtrtrkygnclr.com iyinet

    Can we use this with Google adsense? My adsense advertising making slower for site. My pagespeed score is low. What should i do?
    Thanks.

  • http://www.sajalkayan.com Sajal Kayan

    @iyinet you can use the method described at http://www.aaronpeters.nl/blog/non-blocking-google-adsense-ads-improve-page-speed to ensure adsense doesnt “block” the rest of the page…. however that wont have any affect on your pagespeed score.

    The pagespeed tool itself gives great recommendations… whats outlined above wont make any difference to your score

  • http://www.iyinetfrmtrtrkygnclr.com/ iyinet

    @sajal thanks for link. I am tring it now.

  • http://www.yelesermahallesi.com ispir

    Can we use this with Google adsense?

  • http://www.bazgalvaniz.com galvaniz

    Looking no :/

  • Nitish

    hey how r u man i am new to google dfp not able to understand the software since in my company i am the only targeted guy who has given a responsibility to learn and use this for our company plz help me out how i started this software if u have any ebook related to it ,kindly send me it will be great help to me

  • http://www.sajalkayan.com/dfp-now-officially-supports-asynchronous-rendering.html Sajal Kayan » DFP now officially supports asynchronous rendering!

    [...] DFP launched asynchronous ad loading. For the past few months ive been trying to load ads in a manner where it doesn’t affect rest of the page load, this new [...]

  • Bill Clark

    You can override document.write so that it manipulates DOM elements instead.  I use jQuery:

    document.write = function (text) {
        $(‘#’ + tag).html(text);
    };

    (The ‘tag’ variable is defined elsewhere, and corresponds to the enclosing surrounding my ad.)

    In order to guarantee that only one ad is processed at a time (serialized loading of the ads themselves, yes, but the whole chain can be run asynchronously with respect to the rest of the page rendering) I have a function that checks for the existence of the appropriate  #google_ads_iframe_* element and sets a timeout to call back to itself if it doesn’t find it.

    I had to use this approach because I wanted to pass along targeting variables to DfP that weren’t set until later in the processing (after some content was loaded via AJAX) but it has the side effect of letting me load the ad code asynchronously after the rest of the content has rendered.

blog comments powered by Disqus