广告代码分析
很多第三方的广告系统都是使用document.write来加载广告,如下面的一个javascript的广告链接。
1 |
<script type= "text/javascript" src="http: //gg.5173.com/adpolestar/5173/ |
2 |
;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;ct=js;pu=5173;/?"></script> |
这个javascript请求返回的是这样的一段代码:
2 |
"ad=6FF3F844_33E6_86EE_3B96_D94C1CF1AEC4;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;" + |
5 |
"border='0' width=" 132px " height=" 58px " /></a>" ); |
这种看似有点二的加载方式,但是你却没办法改造它,因为它本身就是第三方的。并且代码都添加了统计的功能,上面的javascript的广告链接每请求一次都会统计一次,生成的代码也有点击统计的功能,也就是说必须以这种方式来进行加载。
document.write是在页面渲染的时候同步进行的,必须要等javascript代码下载好并且document.write执行完后才接着渲染后面的内容,如果广告比较多的话,就会导致页面阻塞,尤其是在页面的首屏插好几个图片尺寸比较大的这种广告,那么阻塞情况就相当明显和严重,会让用户觉得你这个网页很慢。
重写document.write
为了避免阻塞,就不能让document.write方法在页面渲染的时候执行,必须想办法让javascript的广告代码在DOM树就绪(DOM ready)之后才执行,但是在DOM树就绪后执行document.write会重新渲染整个页面,这样也是不行的。document.write虽然是浏览器原生的方法,但是也可以自定义一个方法来覆盖掉原来的方法。在javascript广告代码加载之前,重写document.write,等加载并执行完再改回来。
延迟加载javascript代码
上面比较关键的一步,延迟加载javascript代码,如何实现呢?先尝试通过改写script的type属性,比如将type设置成一个自定义的属性”type/cache”,但这样大部分浏览器(Chrome不会下载)仍然会下载这段代码,但不会执行,在页面渲染的时候下载这么一段代码仍然会阻塞,通过改写script的type并不能实现真正的延迟加载,最多能实现只加载不执行,而且还存在兼容问题。
将script标签放到textarea标签中,等需要加载的时候再读取textarea的内容,这样可以实现真正的延迟加载script,这个方法要感谢玉伯提出的BigRender(墙外)方案。
2 |
<textarea style= "display:none" > |
3 |
<script type= "text/javascript" src="http: //gg.5173.com/adpolestar/5173/ |
4 |
;ap=2EBE5681_1BA3_4663_FA3F_E73D2B83FBDC;ct=js;pu=5173;/?"></script> |
延迟加载script并重写document.write,下面是代码实现:
02 |
* 重写document.write实现无阻塞加载script |
03 |
* @param { Dom Object } textarea元素 |
05 |
var loadScript = function( elem ){ |
06 |
var url = elem.value.match( /src= "([\s\S]*?)" /i )[1], |
07 |
parent = elem.parentNode, |
08 |
// 缓存原生的document.write |
09 |
docWrite = document.write, |
11 |
script = document.createElement( 'script' ), |
12 |
head = document.head || |
13 |
document.getElementsByTagName( 'head' )[0] || |
14 |
document.documentElement; |
17 |
document.write = function( text ){ |
18 |
parent.innerHTML = text; |
21 |
script.type = 'text/javascript' ; |
26 |
script.onreadystatechange = function( e ){ |
27 |
e = e || window. event ; |
28 |
if ( !script.readyState || |
29 |
/loaded|complete/.test(script.readyState) || |
33 |
// 恢复原生的document.write |
34 |
document.write = docWrite; |
35 |
head.removeChild( script ); |
45 |
script.onreadystatechange = null ; |
51 |
head.insertBefore( script, head.firstChild ); |
图片延迟加载的增强版
实现了无阻塞式的延迟加载javascript广告代码,能否进一步优化?如果广告没在首屏出现,能否像通常的图片的延迟加载一样来进行延迟加载?答案是肯定的。对我之前写的图片延迟加载的小插件进行扩展,将原来的图片加载方式(替换src)改成上面的loadScript方式加载就可以实现。当然,仅仅是这样的修改还是会有问题的。如果有多个图片,并且loadScript是同时进行的,而document.write又是全局的方法,保不准在加载A的时候不影响到B,必须让它们一个个的按顺序加载,加载完A之后才能加载B。
队列控制
为了让javascript广告代码按顺序加载就需要一个队列来控制加载。于是又有了下面这段简单的队列控制代码:
03 |
var queue = function( data ){ |
04 |
loadQueue.push( data ); |
05 |
if ( loadQueue[0] !== 'runing' ){ |
10 |
var dequeue = function(){ |
11 |
var fn = loadQueue.shift(); |
12 |
if ( fn === 'runing' ){ |
13 |
fn = loadQueue.shift(); |
17 |
loadQueue.unshift( 'runing' ); |
图片延迟加载插件的使用说明:http://stylechen.com/imglazyload2.html
图片延迟加载的增强版插件下载地址:http://stylechen.com/wp-content/uploads/download/imglazyload.zip
- 关于JavaScript是否会阻塞图片加载
<?php //1.js.php sleep(5); file_put_contents("tmp.txt", __FILE__.'->'.__LINE__.' -&g ...
- 转:JS线程和JS阻塞页面加载的问题
前几日写了一篇文章,介绍了js阻塞页面加载的问题.当时是通过例子来验证的.今天,我介绍一下浏览器内核,从原理上介绍一下js阻塞页面加载的原因. 浏览器的内核是多线程的,它们在内核制控下相互配合以保持同 ...
- PHP + JavaScript + Ajax 实现无刷新页面加载效果
数据源工厂 Json生成方式1 Json生成方式2 数据搬运工 数据加工师 转换类型 加工展示 结果展示 初始页面 点击按钮之后 总结 今天这个实验的思路就是实现一个无刷新的页面加载效果.具体的思路是 ...
- js 利用canvas + flv.js实现视频流 截屏 、本地下载功能实现,兼容火狐,谷歌;canvas截屏跨域问题,无音频视频流加载不显示问题
项目:物联网监控项目----后台视频流管理(前端实现视频截屏功能) 本文就不同视频源分情况展示: 1 本地视频(项目同目录视频)截屏(canvas.getContext("2d).drawI ...
- jquery的 $(function(){ }) = $(document).ready(function(){ }) ,及页面的加载顺序
document.ready和onload的区别:一.JavaScript文档加载完成事件页面加载完成有两种事件一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件) 二.是onloa ...
- php+ajax实现无刷新动态加载数据技术
我们浏览有些网页的时候,当拉动浏览器的滚动条时到页底时,页面会继续自动加载更多内容供用户浏览.这种技术我暂且称它为滚屏加载技术.我们发现很多网站用到这种技术,必应图片搜索.新浪微博.QQ空间等将该技术 ...
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...
- 通过分析iframe和无阻塞脚本关系能让我们更懂iframe
在我上篇文章里,我提到一种使用iframe完成无阻塞脚本加载的方式,因为我对iframe的偏见很大,所以上篇文章里我没有展开讨论这个问题. 文章发表后有位网友问了我这样一个问题,下面是他问题的原文,如 ...
- 无阻塞加载和defer、async
无阻塞加载 把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题.但是少部分新的浏览器已经开始允许 ...
随机推荐
- 设计模式实战系列之@Builder和建造者模式
前言 备受争议的Lombok,有的人喜欢它让代码更整洁,有的人不喜欢它,巴拉巴拉一堆原因.在我看来Lombok唯一的缺点可能就是需要安装插件了,但是对于业务开发的项目来说,它的优点远远超过缺点. 我们 ...
- 对于python装饰器结合递归的进一步理解
对于python装饰器结合递归的进一步理解 代码如下: import functools def memoize(fn): print('start memoize') known = dict() ...
- 史上最全且最简洁易懂的Activity启动流程解析
Activity的启动流程是一个资深Android工程师必须掌握的内容,也是高职级面试中的高频面试知识点,无论是从事应用层开发,还是Framework开发,其重要性都无需我多言.而要真正理解它,就不可 ...
- 图论算法(二)最短路算法:Floyd算法!
最短路算法(一) 最短路算法有三种形态:Floyd算法,Shortset Path Fast Algorithm(SPFA)算法,Dijkstra算法. 我个人打算分三次把这三个算法介绍完. (毕竟写 ...
- PYTHON-错误-函数有返回值未接收导致替换不成功
#1.有返回值,没有赋值,替换不成功 cxj = 'guapi' cxj.replace(cxj,'2b') print(cxj) #2.有返回值,赋值,替换成功 cxj = 'guapi' cxj ...
- Linux 实现密钥免密登录
Linux 实现密钥免密登录 环境:CentOS 7 一. 创建密钥 登录Linux,进入/root/.ssh/目录下 执行ssh-keygen -t rsa创建密钥一直回车即可,因为是免密所以直接回 ...
- 简述 jpg png gif png-8 png-24 的区别
Gif 格式的特点: 1.透明性,GIF是一种布尔透明类型,既可以是全透明,又可以是不透明,但是不可以半透明: 2.动画 GIF支持动画. 3.无损耗性 GIF是一种无损耗的图像格式,也 ...
- 谈谈javascript的基本规范~~~~
1.不要在同一行声明多个变量. 2.请使用===或==来比较true或false或者数值 3.使用对象字面量代替new Array这种形式 4.不要使用全局函数 5.switch语句必须带有defau ...
- .NET Core + K8S + Apollo 玩转配置中心
1.引言 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理 ...
- python基础 Day12
python Day12 生成器python社区,生成器与迭代器看成一种.生成器的本质就是迭代器. 区别:生成器是我们自己用python代码构建的数据结构.迭代器都是提供的,或者转化得来的. 获取生成 ...