浏览器加载js的阻塞与非阻塞

这几天因项目需求,要实现一系列的js文件加载的问题,于是,就按照常规思路写了一通,悲催的是测试后发现问题重重;

为什么会有这么多问题,仔细想来还是对浏览器加载js的原理理解不透,于是我翻阅了大量的资料和自己的一些实践,总结出来以下的内容;

1、js在浏览器中的阻塞

常规理解就是浏览器在加载js时候会阻塞浏览器的渲染操作,但页面性能决定不希望我们在加载js的时候影响页面的渲染,所以我们经常会把js文件放到body之前去加载。而不会把它放在head里去阻塞页面的渲染。那么问题来了,如果我们把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?

其实在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题。但是新的浏览器已经开始允许并行加载js了,也就是说我可以同时下载js文件,但是还是先后顺序执行文件的。

2、document.write 使用

我们一般会用document.write来生成一段广告,经常这样操作:document.write(‘<script id="posAD" type="text/javascript" src="http://192.168.3.107:888/control.js?platformcode=tcy&postioncode=A1&filecode=10030"><\/script>‘);

这样操作也是阻塞的;有同学就问了,你这是外联js,那么内链的呢,我也做过测试,一样的,同样会阻塞。

这样使用的时候一定要记住,要确保他是在dom ready之前去执行,否则它将会重新渲染整个页面。

3、那么如何实现非阻塞呢,那么就需要动态加载js了,通过appendChild(script)这种方式去异步加载js了,其实还可以用xhr对象来处理,但是这样只能解决非跨域问题,跨域xhr就无能为力了。还有一种办法就是新浏览器的defer 和 async 属性了,这样你把它写到head里也不会阻塞浏览器的渲染了。

于是在我明白上述的这样东东之后,我简单的实现一个动态加载js模块:

    //loadJS模块
    (function () {

      var loadJS = function (deps, callback) {
        if(typeof deps == ‘string‘) {
          deps = [deps];
        }

        var len = deps.length;
        var   j = 0 ;
        var  fn = function (){
              j++;
              if(j == len) {
                callback.apply(window);
              }
        };

        for(var i = 0 ; i < deps.length ; i++) {
               _loadMod(deps[i],fn);
        };
      };

      var _loadMod = function(url,fn) {
        var    head = document.head || document.getElementsByTagName(‘head‘)[0] || document.documentElement;
        var  script = document.createElement(‘script‘);
             script.type = ‘text/javascript‘;
             script.charset = ‘utf-8‘;
             script.async = true;
             script.src = url;
             script.onload = script.onreadystatechange = function() {
             if (!script.readyState || script.readyState in {‘loaded‘: 1, ‘complete‘: 1}) {
                    script.onload = script.onreadystatechange = null;
                    fn();
                    head.removeChild(script);
                    script = null;
                }
             }
             head.insertBefore(script, head.firstChild);
       } 

       window.loadJS = loadJS;

    })();

以上内容也是我这两天初步终结出来的,有不对的地方还希望各位童鞋指正。

有兴趣的还可以参考这两篇博客:http://www.w3cfuns.com/blog-5443287-5401014.html 或则 http://www.cnblogs.com/hongcaomao/archive/2012/03/27/javascript_loadad.html

时间: 2024-08-04 09:44:03

浏览器加载js的阻塞与非阻塞的相关文章

无阻塞加载js,防止因js加载不了影响页面显示

浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢,就可以用到无阻塞加载js技术. Dynamic Script Elements 动态脚本元素 DOM允许我们使用Javascript动态创建HTML的几乎所有文档内容,一个新的<script>元素可以非常容易的通过标准DOM创建: var script = document.createElem

Extjs学习----------动态加载js文件(减轻浏览器的压力)

动态加载js文件可以减轻浏览器的压力,本例使用了Ext.window.Window组件,该组件的学习地址:http://blog.csdn.net/z1137730824/article/details/38538277 具体实现步骤: (1)建立dynamic.jsp文件 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String

浏览器加载和渲染html的顺序

浏览器加载和渲染html的顺序 1. IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 2. 在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完). 3. 如果遇到语义解释性的标签嵌入文件(JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载. 4. 样式表在下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行渲染. 5. JS.CSS中如有重定义,后定义函

浏览器加载渲染网页过程解析--总结(三)

转自:http://blog.csdn.net/longeremmy/article/details/8030736 1.浏览器加载和渲染html的顺序 1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完)3.如果遇到语义解释性的标签嵌入文件(JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载.4.并且在下载后进行解析,解析过程中,停止页面所有往下元素的

(转)高性能JavaScript:加载和运行(动态加载JS代码)

浏览器是如何加载JS的 当浏览器遇到一个<script>标签时,浏览器首先根据标签src属性下载JavaScript代码,然后运行JavaScript代码,继而继续解析和翻译页面.如果需要加载的js文件很多很大,则会让人感觉页面加载很慢,影响页面的交互.浏览器在遇到<body>之前,不会渲染页面的任何部分,如果此时<head>中需要加载的js文件很大的话,可能用户开始看到的页面就是一个“白板”,这种情况会立马让用户崩溃. Internet Explorer 8, Fir

浏览器~加载,解析,渲染

昨天为了 了解浏览器是怎么处理(.html..css..js)这些文件,我看了网上的好多资料,这好多资料中,有很多是通过转载.或是转载后加之自己的理解,但是因为自己对专业的词汇理解不好,还有一些作者将不同浏览器的处理过程混着说,总之,看完了,还是有很多疑虑的地方.我先根据昨天了解到的内容总结一下,日后随着学的深了,再回过来补充.2014.11.6 why 为什么要了解浏览器加载.解析.渲染这个过程? 了解浏览器如何进行加载,我们可以在引用外部样式文件,外部js时,将他们放到合适的位置,使浏览器以

浏览器加载渲染网页过程解析 (转)

浏览器的工作机制,一句话概括起来就是:web浏览器与web服务器之间通过HTTP协议进行通信的过程.所以,C/S之间握手的协议就是HTTP协议.浏览器接收完毕开始渲染之前大致过程如下: 从浏览器地址栏的请求链接开始,浏览器通过DNS解析查到域名映射的IP地址,成功之后浏览器端向此IP地址取得连接,成功连接之后,浏览器端将请 求头信息 通过HTTP协议向此IP地址所在服务器发起请求,服务器接受到请求之后等待处理,最后向浏览器端发回响应,此时在HTTP协议下,浏览器从服务器接收到 text/html

异步加载JS

在脚本之家看到了三种异步加载JS的方法: 默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很大的javascript,如果放在页头会导致加载很慢的话,是会严重影响用户体验的. (1) defer,只支持IE defer属性的定义和用法(我摘自w3school网站) defer 属性规定是否对脚本执行进行延迟,直到页面加载为止. 有的 javascript 脚本 document.wr

动态加载JS代码

到处查资料研究js动态脚本的加载,找到以下7种方法,总有一种适合你! 首先我们需要一个被加载的js文件,我在一个固定文件夹下创建了一个package.js,打开后在里面写一个方法functionOne,很简单,代码如下: function functionOne(){ alert("成功加载"); } 后面的html文件都创建在同一个目录下. 方法一:直接document.write 在同一个文件夹下面创建一个function1.html,代码如下: <html> <