大多数浏览器是并行下载组件的,但下载外部脚本时,在脚本的下载、解析并执行完毕之前,不会开始下载任何其他内容。
下面几种方式既可以使用外部脚本又能避免因阻塞导致的减速影响:
(1)XHR Eval
(2)XHR Injection
(3)Script in Iframe
(4)Script DOM Element
(5)Script Defer
(6)document.write Script Tag
代码如下:
1 var Script = {
2 createXHR: function() {
3 var xhr;
4 try {
5 xhr = new XMLHttpRequest();
6 } catch (e) {
7 var progid = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0',
8 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Miscrosoft.XMLHTTP'];
9
10 for (var i = 0, len = progid.length; i < len; i++) {
11 try {
12 xhr = new ActiveXObject(progid[i]);
13 } catch (e) {
14 continue;
15 }
16 break;
17 }
18 } finally {
19 return xhr;
20 }
21 },
22 XHREval: function(url) {
23 var xhr = this.createXHR();
24
25 xhr.onreadystatechange = function() {
26 if (xhr.readyState === 4 && xhr.status === 200) {
27 eval(xhr.responseText);
28 }
29 }
30 xhr.open('GET', url, true);
31 xhr.send(null);
32 },
33 XHRInject: function(url) {
34 var xhr = this.createXHR();
35
36 xhr.onreadystatechange = function() {
37 if (xhr.readyState === 4 && xhr.status === 200) {
38 var script = document.createElement('script');
39 document.getElementsByTagName('head')[0].appendChild(script);
40 script.text = xhr.responseText;
41 }
42 };
43 xhr.open('GET', url, true);
44 xhr.send(null);
45 },
46 scriptDOM: function(url) {
47 var script = document.createElement('script');
48 script.src = url;
49 document.getElementsByTagName('head')[0].appendChild(script);
50 },
51 scriptIframe: function(url) {
52 var iframe = document.createElement('iframe');
53 iframe.setAttribute('id', 'iframeScript');
54 iframe.setAttribute('src', url);
55 document.body.appendChild(iframe);
56
57 //通过getElementById访问iframeScript
58 document.getElementById('iframeScript').contentWindow.createNewDiv();
59
60 /**
61 * iframeScript中的createNewDiv函数
62 * 通过parent访问主页面
63 function createNewDiv() {
64 var newDiv = document.createElement('div');
65 parent.document.body.appendChild(newDiv);
66 }
67 */
68 },
69 scriptTag: function(url) {
70 document.write('<script type="text/javascript" src="' + url + '"><\/script>');
71 }
2 createXHR: function() {
3 var xhr;
4 try {
5 xhr = new XMLHttpRequest();
6 } catch (e) {
7 var progid = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0',
8 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Miscrosoft.XMLHTTP'];
9
10 for (var i = 0, len = progid.length; i < len; i++) {
11 try {
12 xhr = new ActiveXObject(progid[i]);
13 } catch (e) {
14 continue;
15 }
16 break;
17 }
18 } finally {
19 return xhr;
20 }
21 },
22 XHREval: function(url) {
23 var xhr = this.createXHR();
24
25 xhr.onreadystatechange = function() {
26 if (xhr.readyState === 4 && xhr.status === 200) {
27 eval(xhr.responseText);
28 }
29 }
30 xhr.open('GET', url, true);
31 xhr.send(null);
32 },
33 XHRInject: function(url) {
34 var xhr = this.createXHR();
35
36 xhr.onreadystatechange = function() {
37 if (xhr.readyState === 4 && xhr.status === 200) {
38 var script = document.createElement('script');
39 document.getElementsByTagName('head')[0].appendChild(script);
40 script.text = xhr.responseText;
41 }
42 };
43 xhr.open('GET', url, true);
44 xhr.send(null);
45 },
46 scriptDOM: function(url) {
47 var script = document.createElement('script');
48 script.src = url;
49 document.getElementsByTagName('head')[0].appendChild(script);
50 },
51 scriptIframe: function(url) {
52 var iframe = document.createElement('iframe');
53 iframe.setAttribute('id', 'iframeScript');
54 iframe.setAttribute('src', url);
55 document.body.appendChild(iframe);
56
57 //通过getElementById访问iframeScript
58 document.getElementById('iframeScript').contentWindow.createNewDiv();
59
60 /**
61 * iframeScript中的createNewDiv函数
62 * 通过parent访问主页面
63 function createNewDiv() {
64 var newDiv = document.createElement('div');
65 parent.document.body.appendChild(newDiv);
66 }
67 */
68 },
69 scriptTag: function(url) {
70 document.write('<script type="text/javascript" src="' + url + '"><\/script>');
71 }
72 };
各种技术对比:
技术 | 并行下载 | 跨域 | 忙指示器 | 确保顺序 |
Normal Script Src | (IE8,Saf4)a | 是 | IE、Saf4、(FF、Chr)b | IE、Saf4、(FF、Chr、Op)c |
XHR Eval | IE、FF、Saf、Chr、Op | 否 | FF、Chr | -- |
XHR Injection | IE、FF、Saf、Chr、Op | 否 | FF、Chr | -- |
Script In Iframe | IE、FF、Saf、Chr、Opd | 否 | IE、Saf4、FF、Chr | -- |
Script DOM Element | IE、FF、Saf、Chr、Op | 是 | FF、Chr、Saf | FF、Op |
Script Defer | IE、FF3.5、Saf4、Chr2 | 是 | IE、FF、Saf、Chr、Op | IE、FF、Saf、Chr、Op |
document.write Script Tag | (IE、Saf4、Chr2、Op)e | 是 | IE、FF、Saf、Chr、Op | IE、FF、Saf、Chr、Op |
注:
a:脚本并行下载,但其他类型资源的下载仍然被阻塞
b:不支持JavaScript与其它资源并行下载,但支持多个JavaScript之间的并行下载
c:同a
d:在Opera中,脚本不但会并行下载而且会并行执行
e:同a