[分享]使用非阻塞方式并行加载Javascript,降低页面加载时间,该如何解决
[分享]使用非阻塞方式并行加载Javascript,降低页面加载时间
1.目前绝大部分的浏览器都是采取阻塞方式(Scripts Block Downloads)加载Javascript文件的;
如下图所示:
只有当浏览器一个一个下载完所有的script文件时,才会开始并行下载其他资源(css, 图片,网页);
这种机制的好处就是我们可以随意在页面上使用那种JS库中的函数,因为页面肯定是在JS加裁之后呈现的,但是缺点也非常明显:一旦此Javascript文件过大,或网络连接不稳定,整个页面就会被阻塞一段时间,这里有一个 示例。
2.因此一般大型的网站都会采取非阻塞方式加载Javascript来提高性能(降低页面加载时间),Steve 在他的博文中提到了几种方法,如使用iframe, 动态添加script节点等来并行下载javascript文件。不过目前用得最多的应该还是动态添加script节点的方法。如下代码,出自 Nicholas的文章。
3.但是这样带来了另外一个问题,就是在页面加载完的时间Javascript库可能还没有下载完,此时在页面上文件中的函数会出问题,不过解决方法也有很多:
A.在上文的loadScript中有一个callback函数,因此可以,定义一个较小loader的JS文件去加载其他较大的JS文件,并且会定义一个$wait函数,页面上这样使用:
$wait(function(){
……
});
当所以script都加载好时,$wait会直接执行function,如果没加载好,刚推进队列,加载好时再一起执行;这种方式的缺点是无法在较低版本的IE浏览器上执行,因为他们根本就没有script.onreadystatechange事件
B.在JS文件中绑定:即所有的Javascript和绑定代码都写到JS文件中,这种方式的特点是功能会直接跟DOM结构进行绑定,而无需配置,缺点都是整个Site都是统一配置,不利于多变的模块,示例:
//外部JS文件中
C.使用异步绑定,原理就是使用timer来检测要使用的对象是否可用,目前MSN使用的就类似这种方式,
//外部JS文件中, 定义jQuery插件
//页面中
原文在此:http://blog.sina.com.cn/s/blog_54da57aa0100y1rr.html
------解决方案--------------------
支持下。。。
------解决方案--------------------
很好。。。
------解决方案--------------------
楼主可看看$LAB这个插件,就是异步加载js的
1.目前绝大部分的浏览器都是采取阻塞方式(Scripts Block Downloads)加载Javascript文件的;
如下图所示:
只有当浏览器一个一个下载完所有的script文件时,才会开始并行下载其他资源(css, 图片,网页);
这种机制的好处就是我们可以随意在页面上使用那种JS库中的函数,因为页面肯定是在JS加裁之后呈现的,但是缺点也非常明显:一旦此Javascript文件过大,或网络连接不稳定,整个页面就会被阻塞一段时间,这里有一个 示例。
2.因此一般大型的网站都会采取非阻塞方式加载Javascript来提高性能(降低页面加载时间),Steve 在他的博文中提到了几种方法,如使用iframe, 动态添加script节点等来并行下载javascript文件。不过目前用得最多的应该还是动态添加script节点的方法。如下代码,出自 Nicholas的文章。
- JScript code
function loadScript(url, callback){ var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } script.src = url; document.body.appendChild(script); }
3.但是这样带来了另外一个问题,就是在页面加载完的时间Javascript库可能还没有下载完,此时在页面上文件中的函数会出问题,不过解决方法也有很多:
A.在上文的loadScript中有一个callback函数,因此可以,定义一个较小loader的JS文件去加载其他较大的JS文件,并且会定义一个$wait函数,页面上这样使用:
$wait(function(){
……
});
当所以script都加载好时,$wait会直接执行function,如果没加载好,刚推进队列,加载好时再一起执行;这种方式的缺点是无法在较低版本的IE浏览器上执行,因为他们根本就没有script.onreadystatechange事件
B.在JS文件中绑定:即所有的Javascript和绑定代码都写到JS文件中,这种方式的特点是功能会直接跟DOM结构进行绑定,而无需配置,缺点都是整个Site都是统一配置,不利于多变的模块,示例:
//外部JS文件中
- JScript code
(function($){ //定义功能函数 var RowSwitch = function(){ var rowSwitch = this; rowSwitch.init = function(){ …… }; rowSwitch.bind = function(){ $(".ptslist li a").click(function(e){ …… }); }; …… }; //绑定代码 $(function(){ var rowSwitch = new RowSwitch(); rowSwitch.init(); rowSwitch.bind(); }); })(jQuery);
C.使用异步绑定,原理就是使用timer来检测要使用的对象是否可用,目前MSN使用的就类似这种方式,
//外部JS文件中, 定义jQuery插件
- JScript code
(function ($) { var defaults = { …… }; $.fn.rollOver = function (options) { var settings = $.extend(true, {}, defaults, options); }); } $.fn.rollOver.defaults = defaults; })(jQuery); .... window.asyncCanary = 1; //文件结束标志
//页面中
- JScript code
$async = function(canary){....} //异步检测函数定义,这里会定义一个timer,隔一断时间就会检测标志是否已定义; $async("asyncCanary", function(){ //检测asyncCanary,如果已定义则执行绑定 $("#menubar").rollOver({hoverTxt:""....}); });
原文在此:http://blog.sina.com.cn/s/blog_54da57aa0100y1rr.html
------解决方案--------------------
支持下。。。
------解决方案--------------------
很好。。。
------解决方案--------------------
楼主可看看$LAB这个插件,就是异步加载js的