Javascript的加载

最新博客站点:欢迎来访javascript

1. 浏览器加载css

    (1) 同步加载java

        在网页中,浏览器加载js文件的方式是经过<script>标签。以下所示:jquery

//内嵌脚本
<script type="text/javacript">
    // code here!
</script>
//加载外部脚本
<script type="text/javascript src="path/demo.js"></script>

        <script>标签很方便,只要加入后,浏览器即可读取并运行,可是在读取的时候,浏览器是按照<script>标签的出现顺序,读取Javascript文件,而后当即运行,致使在多个文件相互依赖的状况下,依赖性最小的文件必须放在最前面,依赖性最大的必须放在最后面,不然代码会报错,这一点,想必你们在使用bootstrap的时候都深有体会。另外一方面,浏览器采用同步模式加载<script>标签,也就是说,页面会等待JavaScript文件加载完成,而后再运行后面的代码。当存在不少个<script>标签时,浏览器没法同时读取,必须读完一个再读取另外一个,形成读取时间大大延长,页面响应缓慢,影响用户体验。同步模式又称阻塞模式,会阻止浏览器的后续处理,中止后续的解析,只有当前加载完成,才能进行下一步操做,因此默认同步执行才是安全的。但这样若是js中有输出document内容、修改DOM、重定向等行为,就会形成阻塞。因此通常建议把<script>标签放在<body>结尾处,这样能减小页面阻塞。es6

    (2)异步加载ajax

        为了解决这一问题,ES5中采用了DOM方法,动态加载JavaScript脚本文件bootstrap

function loadScript(url) { var script = document.createElement("script"); script.type="text/javascript"; script.src=url; document.body.appendChild(script); }

        这种方式经过建立一个新的<script>标签,并设置其src属性,异步读取javacript文件浏览器

这样不会形成页面阻塞,但会有另外一个问题,若是其余脚本文件依赖于它,此时没法保证此脚本何时可以载入完毕。缓存

        另外一种加载方式是利用defer和async属性,使脚本异步加载。渲染引擎遇到这一行命令,就会开始下载外部脚本,但不会等它下载和执行,而是直接执行后面的命令。defer和async的区别是: defer要等到整个页面在内存中正常渲染结束(DOM结构彻底生成,以及其余脚本执行完成),才会执行;async一旦下载完成,渲染引擎就会中断渲染,执行这个脚本之后,再继续渲染。即defer是渲染完再执行,async是下载完就执行。另外,若是有多个defer脚本,会按照它们在页面中出现的顺序加载,而多个async脚本是不能保证加载顺序的。安全

        IE9及如下版本在延迟实现方面存在一些至关糟糕的错误,致使执行顺序没法保证。 若是你须要支持<= IE9,我建议不要使用defer,若是执行顺序很重要,请包含没有属性的脚本。
<script src="path/demo.js" defer></script>
<script src="path/demo.js" async></script>

        如何选用defer和async。若是使用的script是个模块,而且不依赖任何其它script文件时使用async;若是该脚本依赖其它script或则被其它script依赖,就使用defer;假若脚本文件很小且被一个async script依赖,就使用内嵌script把该文件放在全部async script前面。

        另一种方法是onload事件的异步加载。

(function(){ if(window.attachEvent) { window.attachEvent("load", asyncLoad); } else if(window.addEventListener) { window.addEventListener("load", asyncLoad); } else {
window.onload = asyncLoad;
}
var asyncLoad = function() { var script = document.createElement("script"); script.type="text/javascript"; script.async = true; script.src = ('https:'==document.location.protocol ? 'https://ssl' : 'http:www') + '.baidu.com/demo.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(script, s); }; )();

        这种方法是把插入script的方法放在一个函数里面,而后放在window的onload方法里面执行,这样就解决了阻塞onload事件的触发问题。

        因为Javascript的动态性,还有不少异步加载方法:XHR Injection、XHR eval、Script In Iframe、document.write("<script type='text/javascript' src=' '")等;

        XHR注入:经过XMLHttpRequest来获取Javascript,而后建立一个script元素插入到DOM结构中。ajax请求成功后设置script.text为请求成功后返回的responseText.

var createXHR  = function() { var obj; if(window.XMLHttpRequest) obj = new XMLHttpRequest(); else obj = new ActiveObject("Microsoft.XMLHTTP"); return obj; }; var xhr = createXML(); xhr.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200) { var script = document.createElement("script"); script.text = xhr.requestText; document.getElementsByTagName("head")[0].appendChild(script); } }

        XHR eval(): 与XHR Injection对responseText的执行方式不一样,直接把responseText放在eval()函数里面执行。

var createXHR  = function() { var obj; if(window.XMLHttpRequest) obj = new XMLHttpRequest(); else obj = new ActiveObject("Microsoft.XMLHTTP"); return obj; }; var xhr = createXML(); xhr.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200) { eval(xhr.responseText); $('#btn').click(function() { alert($(this).text()); }); } }

        Script In Iframe: 在父窗口插入一个iframe元素,而后再iframe中执行加载JS的操做。

var insertJS = function(){ alert($); }; var iframe = document.createElement("iframe"); document.body.appendChild(iframe); var doc = iframe.contentWindow.document;//获取iframe中的window
doc.open(); doc.write("<script>var insertJS = function(){};<\/script><body onload='insertJS()'></body>"); doc.close();

2. 延迟加载

        有些JS代码在某些状况下须要使用,并非页面初始化的时候就要用到。延迟加载就是为解决这个问题。将JS切分红许多模块,页面初始化时只将事件处理程序添加到UI元素上,而后其它JavaScript代码的加载延迟到第一次用户交互或者其余条件须要用到的时候再加载。相似图片的懒加载。这样作的目的是能够渐进式地载入页面,尽量快地为用户提供目前须要的信息,其他部分的内容能够在用户浏览该页面时在后台载入。

        JavaScript的加载分为两个部分:下载和执行脚本,异步加载只解决了下载的问题,可是代码在下载完成后就可能会当即执行,在执行过程当中浏览器储与阻塞状态,响应不了任何需求。为了解决JavaScript延迟加载的问题,能够利用异步加载缓存起来,因此不会当即执行,而后在第一次须要的时候再执行。

        第二部份内容的载入能够用建立动态脚本的形式:

window.onload = function() { var script = document.createElement("script"); script.type="text/javascript"; script.src="demo.js"; document.documentElement.firstChild.appendChild("script"); }

3. 按需加载

        能够经过建立一个require方法,包含须要加载的脚本名称和附加脚本加载完成后须要执行的回调函数。

function require(file, callback) { var script = document.getElementsByTagName("script")[0]; var newjs = document.createElement("script"); newjs.onload= function() { callback(); }; newjs.src=file; script.parentNode.insertBefore(newjs, script); }

 

 

参考:

https://www.jb51.net/article/107680.htm

http://es6.ruanyifeng.com/#docs/module-loader

相关文章
相关标签/搜索