【转】JavaScript 的装载和实践

承上启下前边一篇小说《浏览器的渲染原理简介》 ,本文来说下JavaScript的装载和实践。

一般说来来说,浏览器对于 JavaScript 的运营有两大特色:

1) 载入后马上执行

2)
执行时会阻塞页面后续的始末(包涵页面包车型地铁渲染、其余能源的下载)

于是,即使有七个JS文件被引入,那么对于浏览器来说,这么些JS文件将被串行地载入并相继执行。

鉴于JavaScript 可能会操作 HTML文书档案的DOM
树,所以浏览器一般都不会像并行下载CSS文件一律并行下载JS文件,那是JS文件的特殊性造成的。因而,假若您的JavaScript想操作前面包车型客车DOM
成分,浏览器会报错说找不到对象,那是因为JavaScript执行时前边的HTML被阻塞住了,操作DOM
树时还向来不后边的节点。

 

守旧艺术

当你写下如下代码时:

<script type="text/javascript"  src="http://coolshell.cn/asyncjs/alert.js"></script>

大约来说,head里的<script>标签会阻塞后续能源的载入以及一切页面的变通。比如下面这几个示例,在这之中只有一句JS代码(示例):

alert(“hello world”) ;

效果是在加载此JS文件时会弹出三个会话框,由此点击那一个对话框后才会对接二连三财富拓展载入以及对任何页面包车型客车展开转移。

之所以,有无数网站会把 js 放在网页的最后面,恐怕采取window.load、$(document).ready(function(){}) 之类的轩然大波。

除此以外,由于大多数的JavaScript代码并不需求等待页面,大家需求异步载入功效。那大家怎么异步载入呢?

 

document.write 方式

您大概认为 document.write() 格局能够消除不封堵的格局。通过
document.write
方法写入<script>标签的方法就能够执行前边的东西,对于在同二个script 标签内的
JS代码来说是那样的。可是,对于一切页面来说,如故会卡住的。下边是一段测试代码(示例):

<script type="text/javascript" language="javascript">
    function loadjs(script_filename) {
        document.write('<' + 'script language="javascript" type="text/javascript"');
        document.write(' src="' + script_filename + '">');
        document.write('<'+'/script'+'>');
        alert("loadjs() exit...");
    }

    var script = 'http://coolshell.cn/asyncjs/alert.js';

    loadjs(script);
    alert("loadjs() finished!");
</script>

<script type="text/javascript" language="javascript">
   alert("another block");
</script>

依此弹出的对话框为:

loadjs() exit...
loadjs() finished!
hello world
another block

接下来才会来得页面。

 

script
的defer和async属性

IE自从IE6就之处defer 标签,如:

<script defer type="text/javascript" src="./alert.js" ></script>

对此IE来说,那些标签会让IE并行下载JS文件,并且把其实践hold到了任何DOM装载完成,八个defer
的<script>在举办时也会遵守其现出的相继来运营。最重大的是<script>被增长refer
后,其不会卡住后续DOM 的渲染。不过因为refer
只是IE专用,所以一般用的相比较少。

 

我们的HMTL 5也投入了贰个异步载入 JavaScript的属性:async
。无论你对它赋什么样的值,只要它出现,它就起来异步加载
JS文件。不过,async的异步加载会有1个比较严重的难点,那正是它忠实的实践“载入后及时执行”那条规则。所以,纵然它并不打断页面包车型地铁渲染,可是你也不能够控制他实施的主次和时机(示例)。

支撑 async
标签的浏览器如下,Opera还不帮忙(起点那里),所以这么些点子也不是太好。

Ajax 1

 

动态创立DOM的情势

那种办法恐怕是用的最多的了。 

function loadjs(script_filename) {
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', script_filename);
    script.setAttribute('id', 'coolshell_script_id');

    script_id = document.getElementById('coolshell_script_id');
    if(script_id){
        document.getElementsByTagName('head')[0].removeChild(script_id);
    }
    document.getElementsByTagName('head')[0].appendChild(script);
}

var script = 'http://coolshell.cn/asyncjs/alert.js';
loadjs(script);

那种艺术大概成了规范的异步载入js文件的主意(示例)。那种艺术还玩出了
jsonp 的东东。也正是我们能够为script的src
钦定有些后台的剧本(比如PHP),而以此PHP再次来到贰个JavaScript函数,其参数是叁个json
字符串,重临来调用大家先行定义好的 JavaScript
函数。作者的参照示例:t.js 
(这些示例是笔者在此以前在腾讯网征集的一个异步ajax调用的小例子

 

按需异步载入JS

地方的DOM格局的例证化解了异步载入JavaScript的题材,不过没有化解大家想让他按笔者钦点的机遇运营的难点。所以,我们要求把地方的DOM情势绑定到有个别事件上就足以了。

比如:

1) 绑在window.load
事件上(示例

window.load = loadjs("http://coolshell.cn/asyncjs/alert.js")

2)
绑在特定的事件上(示例

<p style="cursor: pointer" onclick="LoadJS()">Click to load alert.js </p>

譬如当大家在点击有个别DOM成分时,才载入我们的JS文件。

 

更多

局地人恐怕会觉得绑定在有个别特定事件上就像过了好几,而在点击时才载入JS又太慢了。那里抛出一个终端难题:大家想要异步地把JS文件下载到用户本地,不过又不执行,仅当大家想要执行的时候才去实践。

小编提议了一种情势,就如多年事先玩preload图片那样,大家得以应用 object
标签(也得以应用 iframe
标签),于是有了下边的代码(示例):

function cachejs(script_filename){
    var cache = document.createElement('object');
    cache.data = script_filename;
    cache.id = "coolshell_script_cache_id";
    cache.width = 0;
    cache.height = 0;
    document.body.appendChild(cache);
}

在Chrome 下按F12(只怕Ctrl+Shit+I),切换来 network页,能够见到 alert.js
文件已经下载明白则却绝非执行弹出
“hello,world”对话框的操作。然后我们再用事先“绑在一定的事件上”的措施,因为浏览器端有缓存了,不会在从服务器上下载
alert.js 文件了,那样就能担保执行进度了。

Ajax,大家还足以用Ajax的办法,比如:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'new.js');
xhr.send('');

说到底再提多个JS库,1个是ControlJS,一个叫HeadJS,专门用来做异步load
javascript文件的。

 

来源:JavaScript 的装载和履行

相关文章