js load js

来源:互联网 发布:淘宝买快排安全吗? 编辑:程序博客网 时间:2024/05/05 16:22

javascript脚本加载 js load block


心细的用户,可以从上面的http瀑布图比较看出:只有等到a.js加载完了,才开始加载b.js,然后再加载图片资源。我们称a.js阻塞b.js。这种现象,称之为js load block。

//filename:index.html<html><head>  <script type="text/javascript" src="a.js"></script>  <script type="text/javascript" src="b.js"></script></head><body>  <img src="http://static.perfgeeks.com/wp-content/uploads/2011/01/p_460_001.jpg" /></body></html>

有没有办法,让这三个不同的资源a.js, b.js, p_460_001.jpg同时加载,减少页面加载时间,避免因阻塞导致的减速影响。通常有以下几个办法

  • 把所有javascript都内嵌在页面中
  • XHR Eval
  • XHR Injection
  • Iframe
  • Script DOM Element
  • Defer
  • document.write

这里着重介绍最常用的XHR Injection和Script DOM Element二种方法

XHR Injection

XHR Injection和XHR Eval注入技巧都是通过XMLHttpRequest来获取Javascript脚本资源。然后,XHR Eval通过javascript函数eval执行脚本。而XHR Injection则是通过创建一个script的DOM元素,然后把XMLHttpRequest的响应注入script中。某些时候,eval会比较慢,所以我们不推荐使用XHR Eval技巧。

<html><head><script type="text/javascript">function load_js(src) {    var xml_http = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();    xml_http.onreadystatechange = function() {      if (xml_http.readyState == 4) {         var script_element = document.createElement('script');         document.getElementsByTagName('head')[0].appendChild(script_element);         script_element.text = xml_http.responseText;      }    }    xml_http.open('GET', src, true);    xml_http.send('');}load_js('a.js');load_js('b.js');</script></head><body><img src="http://static.perfgeeks.com/wp-content/uploads/2011/01/p_460_001.jpg" /></body></html>


上图可以看到,a.js, b.js和图片资源并行加载。但是XHR Injection有一个限制,不支持跨域加载。即获取的脚本必须部署在与页面相同的域中。同时,该技术不能保证脚本的执行顺序。

Script DOM Element

相较于XHR Injection而言,Script DOM Element技巧支持跨域加载,即可以加载来自不同域的text/javascript资源文件。这是因为该技术利用javascript动态创建script DOM元素并且设置src。

<html><head><script type="text/javascript">function load_js(src) {  var script_elem = document.createElement('script');  script_elem.type = 'text/javascript';  script_elem.src = src;  document.getElementsByTagName('head')[0].appendChild(script_elem);}load_js('a.js');load_js('b.js');load_js('http://www.jt-tech.net/misc/jquery.js');</script></head><body><img src="http://static.perfgeeks.com/wp-content/uploads/2011/01/p_460_001.jpg" /></body></html>


上图也解决了javascript加载阻塞产生的减速影响,即a.js、b.js还有跨域jquery.js等并行加载。这种技巧也有一个小小缺陷,就是在某些浏览器(Firefox2.0/3.0/3.1、Safari3.2.1/4.0、Chrome1.0)会阻塞onload事件,影响用户体验

阻塞渲染、阻塞onload、执行顺序

阻塞渲染,当使用script src技术加载脚本时,浏览器停止渲染所有脚本后面的内容。这种阻塞给用户带来十分差劲的用户体验。应该尽量地避免这种情况出现。

//filename:cat bd_i.html<html><head><script type="text/javascript" src="c.php"></script></head><body>hello world</body></html> //filename:vbd_i.html<html><head><script type="text/javascript">function load_js(src) {    var xml_http = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();    xml_http.onreadystatechange = function() {      if (xml_http.readyState == 4) {         var script_element = document.createElement('script');         document.getElementsByTagName('head')[0].appendChild(script_element);         script_element.text = xml_http.responseText;         script_element.type = 'text/javascript';      }    }    xml_http.open('GET', src, true);    xml_http.send('');}load_js('c.php');</script></head><body>hello world</body></html> //filename: c.php<?phpsleep(2);?>function c() {  return 2;}


二幅图对比,我们可以看到那条竖着的蓝线,表示脚本渲染完成。使用script src技术,则等到c.php(text/javascrip)加载完成之后完成的渲染。而使用XHR Injection技术加载脚本,并没有阻塞渲染。
阻塞onload,通常页面的onload要直到所有资源加载完成时才会被触发。如果加载一个较大的javascript文件,用户需要等待更长时间,浏览器状态栏才会显示“完成”,同时还有可能延迟默认输入框获取焦点。导致较差的用户体验。
执行顺序,当一个页面包含多个text/javascript脚本文件的时候。这些高级技术,使得这些脚本同时(并行)加载,受网络与文件大小的影响,脚本文件到到达顺序与开发人员期望的顺序有可能不一致。所以,使用这些高级技术的时候,尽量避免将相互调用的函数分散在不同的文件里面。

原创粉丝点击