How can we keep OpenX from blocking page load?
Asked Answered
G

5

8

We're using OpenX to serve ads on a number of sites. If the OpenX server has problems, however, it blocks page loads on these sites. I'd rather have the sites fail gracefully, i.e. load the pages without the ads and fill them in when they become available.

We're using OpenX's single page call, and we're giving divs explicit size in CSS so they can be laid out without their contents, but still loading the script blocks page load. Are there other best practices for speeding up pages with OpenX?

Godred answered 22/9, 2010 at 14:59 Comment(1)
see https://mcmap.net/q/1326402/-openx-async-tagsCathcart
C
1

OpenX has some documentation on how to make their tags load asynchronously: http://docs.openx.com/ad_server/adtagguide_synchjs_implementing_async.html

I've tested it, and it works well in current Chrome/Firefox.

It takes some manual tweaking of their ad code. Their example of how the ad tags should end up:

<html>
<head></head>

<body>

Some content here.

Ad goes here.

<!-- Preserve space while the rest of the page loads. -->

<div id="placeholderId" style="width:728px;height:90px">

<!-- Fallback mechanism to use if unable to load the script tag. -->

<noscript>
<iframe id="4cb4e94bd5bb6" name="4cb4e94bd5bb6"
 src="http://d.example.com/w/1.0/afr?auid=8&target=
_blank&cb=INSERT_RANDOM_NUMBER_HERE"
 frameborder="0" scrolling="no" width="728"
 height="90">
<a href="http://d.example.com/w/1.0/rc?cs=
4cb4e94bd5bb6&cb=INSERT_RANDOM_NUMBER_HERE"
 target="_blank">
<img src="http://d.example.com/w/1.0/ai?auid=8&cs=
4cb4e94bd5bb6&cb=INSERT_RANDOM_NUMBER_HERE"
 border="0" alt=""></a></iframe>
</noscript>
</div>

<!--Async ad request with multiple parameters.-->

<script type="text/javascript">
    var OX_ads = OX_ads || [];
    OX_ads.push({
       "slot_id":"placeholderId",
       "auid":"8",
       "tid":"4",
       "tg":"_blank",
       "r":"http://redirect.clicks.to.here/landing.html",
       "rd":"120",
       "rm":"2",
       "imp_beacon":"HTML for client-side impression beacon",
       "fallback":"HTML for client-side fallback"
    });
</script>

<!-- Fetch the Tag Library -->

<script type="text/javascript" src="http://d.example.com/w/1.0/jstag"></script>

Some other content here.

</body>
</html>
Concertmaster answered 3/6, 2014 at 21:49 Comment(1)
Hey, that's good news! I haven't been working with OpenX for 2+ years now but it's good to see they're catching up on performance like this.Godred
I
5

We load our ads in iframes to avoid the problem you're having. We size div and the iframe the same, with the iframe pointing to a page which just contains the ad snippet (you can pass the zone and other required options as parameters to that page).

cheers

Lee

Ickes answered 30/9, 2010 at 23:5 Comment(2)
Does loading the ad in an iframe have any disadvantages such as loss of context? (i.e the ad cannot "see" the rest of the page). Or do you pass any required context parameters in the iframe URL?Hagbut
We add keywords and content to the page (not visible from the outer page) as well as the snippet so if they do scan the referring URL they get relevent content.Ickes
B
5

We lazy-load OpenX's code. Instead of putting the single-page call at the top of the page, we put it at the bottom. After the page has loaded, the call will get the banner data and a custom code will add the correct banners in the correct zones.

The code below requires a proper DOM. If you have jQuery, DOMAssistant, FlowJS, etc, the DOM should be fixed for you. This code will work with normal banners with images, flash, or HTML content. It may not work in some cases like when using banners from external providers (adform, etc). For that you may need to hack the code a bit.

How to use it?

  1. add your SinglePageCall code towards the end of your HTML code
  2. add this code under the SPC code.
  3. after half a second or so, your OpenX code should be ready, and the code below will put the banners within the specified DIVs.
  4. Oh, yeah, you need to add to your HTML code some DIVs as place holders for your banners. By default I have these banners set with CSS class "hidden" which totally hides the DIVs (with visibility, display, and height). Then, after the banner in a given DIV is successfully loaded, we remove the hidden class and the DIV (and the banner within) become visible.

Use at your own risk! :) Hope it helps

(function(){
if (!document || !document.getElementById || !document.addEventListener || !document.removeClass) {
return; // No proper DOM; give up.
}
var openx_timeout = 1, // limit the time we wait for openx
oZones = new Object(), // list of [div_id] => zoneID
displayBannerAds; // function.


// oZones.<divID> = <zoneID>
// eg: oZones.banner_below_job2 = 100;
// (generated on the server side with PHP)
oZones.banner_top = 23;
oZones.banner_bottom = 34;



displayBannerAds = function(){
if( typeof(OA_output)!='undefined' && OA_output.constructor == Array ){
  // OpenX SinglePageCall ready!

  if (OA_output.length>0) {

    for (var zone_div_id in oZones){
      zoneid = oZones[zone_div_id];

      if(typeof(OA_output[zoneid])!='undefined' && OA_output[zoneid]!='') {

        var flashCode,
          oDIV = document.getElementById( zone_div_id );

        if (oDIV) {

          // if it's a flash banner..
          if(OA_output[zoneid].indexOf("ox_swf.write")!=-1)
          {

            // extract javascript code
            var pre_code_wrap = "<script type='text/javascript'><!--// <![CDATA[",
              post_code_wrap = "// ]]> -->";

            flashCode = OA_output[zoneid].substr(OA_output[zoneid].indexOf(pre_code_wrap)+pre_code_wrap.length);
            flashCode = flashCode.substr(0, flashCode.indexOf(post_code_wrap));


            // replace destination for the SWFObject
            flashCode = flashCode.replace(/ox\_swf\.write\(\'(.*)'\)/, "ox_swf.write('"+ oDIV.id +"')");


            // insert SWFObject
            if( flashCode.indexOf("ox_swf.write")!=-1 ){
              eval(flashCode);
              oDIV.removeClass('hidden');
            }// else: the code was not as expected; don't show it


          }else{
            // normal image banner; just set the contents of the DIV
            oDIV.innerHTML = OA_output[zoneid];
            oDIV.removeClass('hidden');
          }
        }
      }
    } // end of loop
  }//else: no banners on this page
}else{
  // not ready, let's wait a bit
  if (openx_timeout>80) {
    return; // we waited too long; abort
  };
  setTimeout( displayBannerAds, 10*openx_timeout );
   openx_timeout+=4;
}
};
displayBannerAds();
})();
Businesslike answered 29/10, 2010 at 6:50 Comment(3)
Could you provide a sample of that custom code? I've toyed with replacing the document.write function but had some problems with loading the content into proper containers as we have several banners on the same page.Sigurd
Rafa, is the custom code anything like this: jqueryad.web2ajax.fr ? We found that recently but haven't implemented it yet as a test.Godred
pjmorse> I just realized I never replied to your comment and just updated the answer. I wonder if you got some type of notification. If not, here's a "ping"/"poke" comment, just in case... one year later ;-)Businesslike
C
1

Following @Rafa excellent answer, i'm using this code to invoke OpenX banners after the page loads. I'm using jquery as well and had to add a new replace call for the "document.write" that flash banners use, and replacing it with "$('#"+ oDIV.id +"').append" instead. I'm using a custom "my_openx()" call, to replace "OA_show()". My banners area called by the zone_id and are wrapped inside a div, like this:

<div id="openx-4"><script>wm_openx(4);</script></div>

It's working :)

<script type="text/javascript">             
$is_mobile = false;
$document_ready = 0;
$(document).ready(function() {
    $document_ready = 1;
    if( $('#MobileCheck').css('display') == 'inline' ) {
        $is_mobile = true;
        //alert('is_mobile: '+$is_mobile);
    }
});

function wm_openx($id) {
    if($is_mobile) return false;
    if(!$document_ready) {
        setTimeout(function(){ wm_openx($id); },1000);
        return false;
    }

    if(typeof(OA_output[$id])!='undefined' && OA_output[$id]!='') {

        var flashCode,
            oDIV = document.getElementById('openx-'+$id);

        if (oDIV) {

            // if it's a flash banner..
            if(OA_output[$id].indexOf("ox_swf.write")!=-1) {

                // extract javascript code
                var pre_code_wrap = "<script type='text/javascript'><!--// <![CDATA[",
                    post_code_wrap = "// ]]> -->";

                flashCode = OA_output[$id].substr(OA_output[$id].indexOf(pre_code_wrap)+pre_code_wrap.length);
                flashCode = flashCode.substr(0, flashCode.indexOf(post_code_wrap));

                // replace destination for the SWFObject
                flashCode = flashCode.replace(/ox\_swf\.write\(\'(.*)'\)/, "ox_swf.write('"+ oDIV.id +"')");
                flashCode = flashCode.replace(/document.write/, "$('#"+ oDIV.id +"').append");


                // insert SWFObject
                if( flashCode.indexOf("ox_swf.write")!=-1 ) {
                    //alert(flashCode);
                    eval(flashCode);
                    //oDIV.removeClass('hidden');
                }// else: the code was not as expected; don't show it


            }else{
                // normal image banner; just set the contents of the DIV
                oDIV.innerHTML = OA_output[$id];
                //oDIV.removeClass('hidden');
            }
        }
    }
    //OA_show($id);
}
</script>
Consolidation answered 4/7, 2012 at 15:40 Comment(0)
O
1

I was looking for this to load advertising from my openX server only when the advertising should be visible. I'm using the iFrame version of openX which is loaded in a div. The answer here put me on my way to solving this problem, but the posted solution is a bit too simple. First of all, when the page is not loaded from the top (in case the user enters the page by clicking 'back') none of the divs are loaded. So you'll need something like this:

$(document).ready(function(){
   $(window).scroll(lazyload);
   lazyload();
});

also, you'll need to know what defines a visible div. That can be a div that's fully visible or partially visible. If the bottom of the object is greater or equal to the top of the window AND the top of the object is smaller or equal to the bottom of the window it should be visible (or in this case: loaded). Your function lazyload may look like this:

function lazyload(){
   var wt = $(window).scrollTop();    //* top of the window
   var wb = wt + $(window).height();  //* bottom of the window

   $(".ads").each(function(){
      var ot = $(this).offset().top;  //* top of object (i.e. advertising div)
      var ob = ot + $(this).height(); //* bottom of object

      if(!$(this).attr("loaded") && wt<=ob && wb >= ot){
         $(this).html("here goes the iframe definition");
         $(this).attr("loaded",true);
      }
   });
}

Tested on all major browsers and even on my iPhone, works like a charm!!

Ongoing answered 25/2, 2013 at 10:4 Comment(0)
C
1

OpenX has some documentation on how to make their tags load asynchronously: http://docs.openx.com/ad_server/adtagguide_synchjs_implementing_async.html

I've tested it, and it works well in current Chrome/Firefox.

It takes some manual tweaking of their ad code. Their example of how the ad tags should end up:

<html>
<head></head>

<body>

Some content here.

Ad goes here.

<!-- Preserve space while the rest of the page loads. -->

<div id="placeholderId" style="width:728px;height:90px">

<!-- Fallback mechanism to use if unable to load the script tag. -->

<noscript>
<iframe id="4cb4e94bd5bb6" name="4cb4e94bd5bb6"
 src="http://d.example.com/w/1.0/afr?auid=8&target=
_blank&cb=INSERT_RANDOM_NUMBER_HERE"
 frameborder="0" scrolling="no" width="728"
 height="90">
<a href="http://d.example.com/w/1.0/rc?cs=
4cb4e94bd5bb6&cb=INSERT_RANDOM_NUMBER_HERE"
 target="_blank">
<img src="http://d.example.com/w/1.0/ai?auid=8&cs=
4cb4e94bd5bb6&cb=INSERT_RANDOM_NUMBER_HERE"
 border="0" alt=""></a></iframe>
</noscript>
</div>

<!--Async ad request with multiple parameters.-->

<script type="text/javascript">
    var OX_ads = OX_ads || [];
    OX_ads.push({
       "slot_id":"placeholderId",
       "auid":"8",
       "tid":"4",
       "tg":"_blank",
       "r":"http://redirect.clicks.to.here/landing.html",
       "rd":"120",
       "rm":"2",
       "imp_beacon":"HTML for client-side impression beacon",
       "fallback":"HTML for client-side fallback"
    });
</script>

<!-- Fetch the Tag Library -->

<script type="text/javascript" src="http://d.example.com/w/1.0/jstag"></script>

Some other content here.

</body>
</html>
Concertmaster answered 3/6, 2014 at 21:49 Comment(1)
Hey, that's good news! I haven't been working with OpenX for 2+ years now but it's good to see they're catching up on performance like this.Godred

© 2022 - 2024 — McMap. All rights reserved.