用ControlJS优化阿里妈妈广告

2019-03-19 07:05:46来源: 淘宝UED 阅读 ()

新老客户大回馈,云服务器低至5折

长时间以来阿里妈妈的广告载入策略一直存在些问题,很多页面也因为阻塞式的广告载入而被拉低性能,影响用户体验。毕竟阿里妈妈广告的渲染依赖于诸多嵌套的document.write。ControlJS的目标就是解决js的阻塞式渲染,因此灵玉急不可耐想与同仁们共同去揭秘ControlJS……

Steve Souders在2010年12月份发布了ControlJS项,该项目是让开发者更好的去控制javascript文件的下载和执行,从而提高了页面脚本的加载速度。

Steve提出了一个非常具有创造性的思想,就是预先异步下载javascript文件而不解析执行,直到需要的javascript处理时才去真正的执行。这一点得到了很多人的关注与验证。Nicholas Zaka也因ControlJS引发了很多思考,并分析了ControlJS和LABjs 的区别所在,详细内容可以阅读Thoughts on script loaders和Separating JavaScript download and execution。Steve使用3篇博闻详细介绍了ControlJS:异步加载、延迟执行、重写document.write。

ControlJS的原理

异步加载

ControlJS本身是异步进行加载的,首先将script的标签type属性值更改为浏览器无法识别的类型,这样浏览器不会认为这是一个脚本。本身异步加载的ControlJS执行时开始遍历type=”text/cjs”的script标签(包括内嵌脚本),如果存在”DATA-CJSSRC”属性将创建IMAGE或者OBJECT对象(依赖浏览器而选择),去异步预下载脚本文件并缓存文件,直到window.onload时解析并执行javascript,同时第二次去遍历遗漏的script标签。具体操作可看Async WITH ControlJS

延迟执行

浏览器在解析执行javascript阶段是阻塞任何操作的,这时的浏览器处于假死状态,Steve分析了美国的Alexa前10名网站的脚本初始需要加载执行情况,发现只有29%是需要页面加载时初始化解析执行的,而其他71%的脚本是在触发交互时才会执行,压缩后这些脚平均加载是229 kB,未压缩是500KB,这是个大量的数据。

我们希望的结果是在页面加载中不去解析执行javascript,只是提前预下载好文件。例如通用的点击弹出二级导航,用户有可能永远都没有点击导航的行为,此时导航的功能脚本根本毫无用处。但是人们在点击导航时不希望等太久javascript的执行,所以ControlJS会提前下载文件,这样javascript只是解析执行,不会花时间放到下载文件上。代码一目了然,具体操作可看Menu WITH ControlJS

重写document.write

在默认情况下这些异步脚本都是在window.onload解析执行,如果此时脚本调用window.write方法,将导致一个不希望发生的问题,就是整个页面被window.write的输出内容替换,所有页面内容将被删除,ie下将处于停滞状态。产生问题的原因是由于在docuemnt被加载完后调用docuemnt.write方法时将会自动去触发document.open,写入任何处于打开状态的doucment都将会会替换整个页面的内容。这便导致目前为止所有异步脚本无法延迟document.write的问题,ControlJS的处理方法是重写docuemnt.write,如下:

以下为引用的内容:
CJS.docwriteOrig = document.write;
document.write = CJS.docwrite;

ControlJS创建一个dom元素(span),将其插入当前被解析执行的script标签之前,并且设置SPAN的innerHTML的值为docuemnt.write的内容。具体操作可看document.write WITH ControlJS

用ControlJS优化阿里妈妈广告

对于现在大部分的广告形式都是采用document.write方式写入,无法将这些内容异步处理是开发者非常头疼的问题。ControlJS可以为我们解决这类烦恼。

没有应用ControlJS的网络图。DEMO可以看http://chesihui.github.com/ad-demo.html

应用ControlJS优化后的网络图。DEMO可以看http://chesihui.github.com/ControlJS-demo.html

ControlJS的局限性

ControlJS存在一个问题是在document.write中多层嵌套script标签时,页面仍然存在触发document.open的问题。查看源代码发现在执行完一个javascript后都会恢复document.write的原生方法:

document.write = CJS.docwriteOrig;

动态脚本的异步加载,同样使得document.write方法也是异步执行,因此不能恢复document.write的原生功能。复现的情况如DEMO。注释这段脚本虽然解决了不触发window.open的问题,但是同样的异步加载执行导致无法正确定位广告写入的位置。对于阿里妈妈广告设置alimama_type=”i”的时候,载入图片广告是根据多层document.write实现的,只能正确渲染最后一个图片广告。复现如DEMO

因为ControlJS的异步加载不存在任何依赖顺序,所有脚本都是并行加载执行,如果你的页面存在太多依赖关系,ControlJS将不会适合你的项目。

最后总结ControlJS为我们做了什么事,利弊还需要自己去权衡:

1、异步下载所有脚本

2、同时处理内嵌与外链脚本

3、延迟脚本的执行直到页面被渲染完

4、允许脚本只下载不执行

5、解决了异步脚本中存在docuement.write的问题

6、ControlJS本身是异步加载

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:团购网如何成功实现平台化转型

下一篇:地方性装修网站运营策划浅析