忽略技术细节,通过一段伪代码来描述LABjs里面的实现,大致为:
首先判断是否对请求的脚本进行预加载(是否进行预加载的判断条件看伪代码注释);
如进行预加载,再判断浏览器是否支持真正的预加载;如支持真正的预加载,则预加载之;如否,判断请求的脚本是否跟当前页面同域,如实,采用XHR Injection,如否,采用Cache Trick;
如不进行预加载,判断浏览器支不支持script元素的async属性(见伪代码注释),如是,设置async属性,并请求脚本文件;如否,直接通过script元素加载脚本文件;
if(ifPreloadScript){ //当请求的脚本文件是否进行预加载:1、需要预加载 2、浏览器支持预加载 if(supportRealPreloading){ //如果支持真正的预加载 if(supportPreloadPropNatively){ //支持通过设置script标签的preload属性,实现script的预加载,以及分离加载和执行 //Nicholas C. Zakas大神的美好愿望,尚未有浏览器支持:/blog/2011/02/14/separating-javascript-download-and-execution/ script.onpreload = callback; script.newPreload = true; script.src = targetUrl; }else{ script.onreadystatechange = callback; //其实就是指IE浏览器,假设指定了script元素的src属性,IE浏览器里会立即加载 script.src = targetUrl; //即使script元素没有被插入页面,callback为预加载后的回调 } } else if(inSameDomain){ //非跨域,采用XHR Injection:请求的脚本与当前页面处于同一个域 xhr = new XMLHttpRequest(); //由于上个判断已经将IE无情地抛弃在这个条件分支之外,所以大胆地用 new XMLHttpRequest()吧 xhr.onreadystatechange = callback; xhr.open("GET",targetUrl); xhr.send(); } else{ //最无奈的后招,Cache Trick,新版chromei已经不支持 script.onload = callback; script.type = 'text/cache'; script.src = targetUrl; } }else{ if(canContrlExecutionOrderByAsync){ //如果能够通过script元素的async属性来强制并行加载的脚本顺序执行 //kyle大神着力推进的提案,目前已被html5小组接受并放入草案:/Dynamic_Script_Execution_Order#My_Solution script.onload = callback; script.async = false; //将script元素的async设为false,可以保证script的执行顺序与请求顺序保持一致 script.src = targetUrl; } else{ script.onload = callback; script.src = targetUrl; } }
实际上,当你在页面创建一个img节点,并将其src指向一个脚本文件,在部分浏览器里同样能够起到文件预加载的作用,那么LABjs的作者是不是没有想到这一点呢?
您可能感兴趣的文章: