高性能js--加载和运行

浏览器是如何加载js的?

当浏览器遇到一个<script>标签的时候,浏览器首先根据标签的scr属性下载js代码,然后运行js代码,继而继续解析和翻译页面,浏览器在遇到<body>标签之前是不会渲染任何部分的,如果此时<head>中需要加载的js文件很多很大的话,页面则会加载很慢,用户可能看到的页面就是一个白板,影响页面的交互!

Internet Explorer 8, Firefox 3.5, Safari 4, 和Chrome 2允许并行下载js文件,加快了js的下载时间,但是浏览器支持并行下载的数量有限制,一旦并行下载数量超过浏览器允许的数量,还是会堵塞其他资源的下载。

解决方案:

1.将脚本放在页面底部

一种常见的做法就是将<script>标签放在闭合的</body>之前,这样就可以先把页面展示给用户,让页面加载的速度显示不是很慢,这时最好将css文件放在head中,一遍加载DOM一遍渲染样式。

2.成组下载脚本

多个http请求也会降低页面性能,为了提高性能,我们可以将多个脚本文件放到一个文件中下载,这虽然减少了http请求,但是每次发布之前都要合并文件,并不是很好的解决方法,为此,我们可以采用成组的下载方式来达到目的,成组下载就是一次请求多个脚本文件。例如:

http:www.3c.com/ss.ss?file1.js&file2.js...

每次向服务器的固定服务请求下载多个文件,服务器将多个文件合并到一起返回给客户端,这是html页面包含多个外部js的最佳方法。

3.延时加载

如果js文件又大又多,那么无论我们怎么压缩文件减少http请求数,js的加载都会占用一定的时间,这时比较好的方法是等页面加载完成后再加载js,也就是在window.onload事件发出之后开始下载代码。

延迟加载的一个通用做法是动态的创建脚本元素,一个新的<script>元素可以非常容易的通过DOM函数创建:

var script = document.createElement("script");

script.type="text/javascript";

script.src="***.js";

document.getElementByTagName("head")[0].appendChild(script);

当script元素被添加到页面之后便开始下载脚本文件。这样无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程,当js文件下载完成后,返回的代码通常被立即执行(除了FF和Opera,她们将待此前的所有动态脚本节点执行完毕)

当动态加载的script只是其他script调用的接口时,就会出现问题,因为调用代码不知道被调用的接口是否已加载完毕,还好目前的主流浏览器都能够跟踪节点是否加载完毕!

FF, Opera, Chrome和Safari3+会在节点接收完成后发出一个load事件;IE则是发出一个readystatechange事件,<script>元素有一个readyState属性,它的值随着下载过程而改变。readyState有5种取值:uninitialized(默认状态),loading(下载开始),loaded(下载完成),interactive(下载完成但尚不可用),complete(所有数据已准备好)。微软文档上说,这些取值不一定全部出现,有时script会得到loaded不出现complete,有时script会得到complete不出现loaded。最安全的做法就是,在readystatechange事件中检查这两种状态,当出现两种状态之一时,删除readystatechange句柄,以避免事件不会被执行两次。

代码如下所示:

function loadScript(url, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
};

如果要加载多个文件,并且要保证顺序,则可以采用将上述函数串联的方式实现。

动态脚本加载是最常用的JavaScript非阻塞下载方式,因为它跨浏览器而且简单易用。

 

posted @ 2016-06-02 17:53  花开在半夏  Views(456)  Comments(0)    收藏  举报