`
hyshucom
  • 浏览: 809341 次
文章分类
社区版块
存档分类
最新评论

编写高性能的JavaScript-Ajax数据传输之MXHR

 
阅读更多

动态载入脚本

这个技术的特点克服了XHR最大的缺点:跨域访问。使用如下:

varscriptElement=document.createElement('script');

scriptElement.src='http://any-domain.com/javascript/lib.js';

document.getElementsByTagName('head')[0].appendChild(scriptElement);

动态载入脚本不像XHR那样可以随意设置请求头部,参数只能通过GET发送,只有脚本从服务器完全返回以后你才能访问脚本。

由于这种方式的响应结果是可执行的JS代码,不需要特殊的处理和分析,因而性能十分可观。不过你仍然需要注意,使用这种方式时你对服务器完全没有控制,你无法获得脚本载入期间的信息。而且你也要意识到动态载入的脚本一旦加载完成,它就能够对本页面的数据内容进行修改、转发或者重定向,所以使用时需要格外小心。

更多信息可以看这里:http://book.51cto.com/art/200812/99672.htm

MulipartXHR

这个是以上Ajax请求数据几种方式中最新的技术。MXHR的特点是,只使用一个请求来从服务器将资源发送给客户端,只要组装好了不论是CSS文件、脚本文件、HTML片段还是base64编码的图片。客户端以字符串的形式接受,然后根据MIME类型和其它传输的信息来解析。

示例-使用一个请求下载多个图片资源:

varreq=newXMLHttpRequest();

req.open('GET','rollup_images.php',true);

req.onreadystatechange=function(){

if(req.readyState==4){

splitImages(req.responseText);

}

};

req.send(null);

首先请求页面,然后将响应数据利用方法解析。当然这需要服务器首先要将图片信息转化为base64编码的字符串,同时你需要指定一个连接符号,以便在客户端分割这些字符串。

假定分割符是unidcode编码的1

functionsplitImages(imageString){

varimageData=imageString.split("\u0001");

varimageElement;

for(vari=0,len=imageData.length;i<len;i++){

imageElement=document.createElement('img');

imageElement.src='data:image/jpeg;base64,'+imageData[i];

document.getElementById('container').appendChild(imageElement);

}

}

任何能够在JS中通过字符串处理的数据类型都可以使用这种方式传输。以下是几个常用函数:

functionhandleImageData(data,mimeType){

varimg=document.createElement('img');

img.src='data:'+mimeType+';base64,'+data;

returnimg;

}

functionhandleCss(data){

varstyle=document.createElement('style');

style.type='text/css';

varnode=document.createTextNode(data);

style.appendChild(node);

document.getElementsByTagName('head')[0].appendChild(style);

}

functionhandleJavaScript(data){

eval(data);

}

MXHR传输的数据越来越庞大时,最好的方式是接受一部分数据以后立刻开始处理,而不是等待全部数据加载完成再处理。通过监听XHRreadyState3来处理。

varreq=newXMLHttpRequest();

vargetLatestPacketInterval,lastLength=0;

req.open('GET','rollup_images.php',true);

req.onreadystatechange=readyStateHandler;

req.send(null);

functionreadyStateHandler{

if(req.readyState===3&&getLatestPacketInterval===null){

//Startpolling.

getLatestPacketInterval=window.setInterval(function(){

getLatestPacket();

},15);

}

if(req.readyState===4){

//Stoppolling.

clearInterval(getLatestPacketInterval);

//Getthelastpacket.

getLatestPacket();

}

}

functiongetLatestPacket(){

varlength=req.responseText.length;

varpacket=req.responseText.substring(lastLength,length);

processPacket(packet);

lastLength=length;

}

一旦readyState3第一次触发,一个计时器启动。每隔15ms检测新数据,当找到一个事先约定的分隔符之后收集数据,然后处理这部分数据。

更完美的实现比较复杂但是值得研究,你可以看看这里:http://techfoolery.com/mxhr/

这个技术的缺点就是获取的数据你无法缓存,比如图片、CSS文件等;另外就是老版本的IE不支持监听readyState3,也不支持dataURLs。(IE8支持,IE6IE7需要变通方法)

不过由于它的优点实在是吸引人,所以这些情况你最好使用MXHR

1)如果这个页面包含很多其他页面不需要的资源,尤其是图片;

2)如果站点的每个页面的脚本或CSS都已经组装为一个独特的请求,亦即站点内跨页面访问没有共同的请求。

减少HTTP请求能够全面提升页面的性能,尤其是你需要传输100张图片,只用一个请求通常能为站点的用户体验带来质的飞跃。测试页面:http://techfoolery.com/mxhr/

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics