资讯专栏INFORMATION COLUMN

如何优雅高效地插入百度广告

ISherry / 1994人阅读

摘要:什么是百度广告最近跟百度广告打了会交道,如果您正在或者即将和百度广告打交道,那太好了,本文一定会让您不虚此行。插入到新闻信息流将百度广告插入到新闻信息流,这是很普遍的做法。总结对于百度广告在不同环境中的投放,有不同的处理方式。

什么是百度广告

最近跟百度广告打了会交道,如果您正在或者即将和百度广告打交道,那太好了,本文一定会让您不虚此行。百度广告,即百度联盟广告,在 这里 进行注册后,经过 一些配置,便可以生成一段 js,将该 js 插入到 HTML 页面中,便能出现百度的广告。

恩,百度广告您一定见过,随便截张图:

随便给一段生成的百度广告代码感受下:


以上代码如何能够展现广告?最重要的原因是 cm.js 中将广告内容用 document.write 方法输出。

一般场景

一般场景,也是最简单的使用,需要广告出现在哪个位置,就把该段 js 放在哪个位置。非常容易理解,因为广告的生成用的是 document.write,所以执行到该段 js 时,会同步输出广告内容。

使用方式大概这样:











异步加载

以上的一般场景下,如果有性能瓶颈,很显然是因为百度广告图片加载的问题,js 的加载并不是首要原因(js还有缓存)。出于好奇,还是首先对 cm.js 试试能否异步加载。



控制台有个 warning,但是广告也出来了:

之前我们说到百度广告是用 document.write 同步输出到页面上的,很显然,并不能异步加载有 document.write 方法的 js 文件(到底是重写页面呢,还是重写页面呢),所以会有该 warning。但是,为什么会有广告呢?

这是因为百度有一套 "备胎" 方案。当 cm.js 内部判断该 js 是被异步加载的时候,随即执行这套备胎方案:

createBackupWrapper: function(t) {
    try {
        var e = document.getElementsByTagName("script")
          , i = e[e.length - 1];
        if (i) {
            var n = i.parentNode;
            if (n) {
                var o = document.createElement("div");
                return o.id = t.containerId,
                n.insertBefore(o, i),
                !0
            }
        }
    } catch (r) {}
    return !1
    },

代码写的很清楚,就是把广告元素插入到最后一个 script 标签的前面。为了保证广告所在的位置即是我们希望的位置,很显然最后一个 script 元素必须就是 cm.js

这样理解的话,我们似乎可以得出这样一个结论:当广告位置在页面最底部时(并且只有一处广告位),我们可以对这段广告的 js 进行如上的异步加载。但是 js 异步加载了,广告所需要的图片还得请求,标签页上的小圈圈还是一直在转,所以我觉得对 cm.js 文件进行异步加载,并没有什么卵用。

事实上,cm.js 内部就提供了异步加载的方案 -> 广告位异步加载代码

HELLO WORLD

这样不仅 cm.js 只需加载一次,而且调用也方便多了。(好吧,之前的异步测试算是无用功)

延迟加载

单纯的异步加载对于页面整体的加载速度似乎并没有什么提升(广告图片略多),是否可以用 setTimeout 进行延迟的异步加载?ok,我们对之前的代码进行一点改造,用一个定时器延迟执行 scriptDomElement 函数。



前面说了,异步加载仅适用于 cm.js 作为最后一个 script 标签的情况,也就是广告在页面最底部的情况。what"s more,经过这样的处理,大多数情况下是可以看到广告的,但是小部分情况广告无法展现,究其原因,楼主觉得是 cm.js 内部对该 js 是否是异步加载无法精确判断。

所以楼主觉得,如果可以接受某些机器下无法展现百度广告,这个方法还是可以一试的。

恩,其实我们完全可以用 cm.js 提供的 BAIDU_CLB_fillSlotAsync 方法和 setTimeout 进行配合。

重写 document.write

强势插入硬广一枚:楼主 Github 求关注~

非常简单,写个简单的 DEMO(重写完后记得改回来,DEMO 中没改回来):


Hello world!


如何能做到延迟加载?我们可以采用 BigRender 的思路,将广告代码放在 textarea 标签中,当 textarea 出现在视野中时,取出广告代码执行。参考雨夜带刀的代码:

延迟加载script并重写document.write,下面是代码实现: var loadScript = function( elem ){ var url = elem.value.match( /src="([sS]*?)"/i )[1], parent = elem.parentNode, // 缓存原生的document.write docWrite = document.write, // 创建一个新script来加载 script = document.createElement( "script" ), head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; // 重写document.write document.write = function( text ){ parent.innerHTML = text; }; script.type = "text/javascript"; script.src = url; script.onerror = script.onload = script.onreadystatechange = function( e ){ e = e || window.event; if( !script.readyState || /loaded|complete/.test(script.readyState) || e === "error" ){ // 恢复原生的document.write document.write = docWrite; head.removeChild( script ); // 卸载事件和断开DOM的引用 // 尽量避免内存泄漏 head = parent = elem = script = script.onerror = script.onload = script.onreadystatechange = null; } } // 加载script head.insertBefore( script, head.firstChild ); };

如果有多个广告片段,因为 document.write 是全局方法,所以不得不维护个脚本队列,一个一个执行,又退化成了同步执行脚本。如果异步并发执行的话,很可能广告的位置会出现对调现象。当然,有些百度广告并不会十分在乎顺序,比如下面要说的新闻信息流。

其实我觉得如果要延迟加载某些特定位置的广告区域,可以用 BAIDU_CLB_fillSlotAsync 方法,将该方法所在的代码塞入 textarea 中。 有一点需要注意的是,BAIDU_CLB_fillSlotAsync 必须指定广告位置的 DOM id。

插入到新闻信息流

将百度广告插入到新闻信息流,这是很普遍的做法。

比如网易:

那么如何将广告插入到新闻信息流当中去呢?我们还是可以用重写 document.write 的方法。

举个简单的例子:


重写一个系统的方法毕竟不是什么好事,网易、 头条新闻 采用的都是另一种方法,套一个 iframe,非常巧妙。

index.htm 文件:


ad.htm 文件:


当然,一些样式方面的细节还需要自己去把握,这里只提供一个思路。

总结

对于百度广告在不同环境中的投放,有不同的处理方式。主要有三种:

利用 cm.js 中的 BAIDU_CLB_fillSlotAsync 方法(该方法需要广告位置的 DOM id)

重写 document.write

新建 iframe,在该 iframe 中同步输出广告代码

仁者见仁智者见智吧。

Read more:

重写document.write实现无阻塞加载js广告

让document.write的广告无阻塞的加载

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79249.html

相关文章

  • 实用的IT类网站及工具大集合

    摘要:整理的一些实用的类网站及工具。链接云适配有时候我们做出的网站没有用到响应式布局,也可能我们的网站的像素宽度已经规定成具体的多少像素了。同时提供多个开放,功能实用,非常强大。 整理的一些实用的IT类网站及工具。 1.聚合数据 大家在开发过程中,可能会用到各种各样的数据,想找一些接口来提供一些数据。比如天气预报查询,火车时刻表查询,彩票查询,身份证查询等等。有了这个接口,直接调用即可。各种...

    rollback 评论0 收藏0
  • 前端资源收集整理

    摘要:工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 Github版本:Front-End Resource Collection 前端相关资源汇总 学习指导 精华文章 Web前端的路该怎么走?:文章超长,但是干货超级多,值得反复精读! 听说2017你想写前端?:适合于已经度过了小白阶...

    awesome23 评论0 收藏0
  • 前端资源收集整理

    摘要:工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 Github版本:Front-End Resource Collection 前端相关资源汇总 学习指导 精华文章 Web前端的路该怎么走?:文章超长,但是干货超级多,值得反复精读! 听说2017你想写前端?:适合于已经度过了小白阶...

    antyiwei 评论0 收藏0
  • 前端资源收集整理

    摘要:工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 工作原因,最近一年断断续续写了一点前端代码,收集整理了一些资料,和大家共享。 Github版本:Front-End Resource Collection 前端相关资源汇总 学习指导 精华文章 Web前端的路该怎么走?:文章超长,但是干货超级多,值得反复精读! 听说2017你想写前端?:适合于已经度过了小白阶...

    KavenFan 评论0 收藏0
  • 阿里开源首个深度学习框架 X-Deep Learning!

    摘要:此前,在月底,阿里妈妈就公布了这项开源计划,引来了业界的广泛关注。突破了现有深度学习开源框架大都面向图像语音等低维稠密数据而设计的现状,面向高维稀疏数据场景进行了深度优化,并已大规模应用于阿里妈妈的业务及生产场景。 showImg(https://segmentfault.com/img/remote/1460000017508808); 刚刚,阿里妈妈正式对外发布了X-Deep Le...

    hankkin 评论0 收藏0

发表评论

0条评论

ISherry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<