当浏览器遇到<script>标签时,页面的加载、介些都会停下来,运行此javascript代码,然后再继续加载。这种事情同样会发生在那些以"src"属性调用的外部脚本,浏览器首先下载外部文件的代码,这要占用一些时间,然后在运行这些代码,这又要占用一些时间。此过程中,页面的解析与用户的交互都是阻塞的。
脚本的位置
不管是内联脚本还是外部脚本,都应该尽量放在<body>
标签结束之前(除非某些脚本需要在页面加载完之前调用),这样可以保证在运行脚本之前,页面已经基本加载完成。
非阻塞脚本
延时脚本
可以给script
标签添加一个属性 - defer ,这个属性表明:元素中的脚本不打算修改DOM,因此代码可以稍后执行。带有这个属性的任何script
元素中的脚本都不会在DOM加载完之前执行,如果是外部脚本,这些脚本首先并行下载,而不会执行,所以不会阻塞页面的加载。实例代码如下:<script src="./script/file1.js" defer>
动态脚本元素
DOM允许你通过脚本来创建script
元素,像下面这样:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "./script/file1.js";
document.getElementsByTagName("head")[0].appendChild(script);
此文件元素添加到页面后立即开始下载。此技术的重点在于:无论在何处启动下载,脚本的下载和运行都不会阻塞页面的处理过程。
为方便使用,我整合了一个动态加载脚本的方法:
function loadJS(url, callback) {
var script = document.creatElement("script");
script.type = "text/script";
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);
}
XMLHttpRequest 脚本注入
另一个以非阻塞的方式获得脚本的方法是使用XHR对象将脚本注入到页面中。此技术先创建一个XHR对象,然后下载脚本文件,接着用一个动态的script
元素将javascript代码注入页面:
var xhr = new XMLHttpRequest();
xhr.open("get", "./scripts/file1.js", true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 400) {
var script = document.createElement("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);
};
此方法的限制是,你必须下载同一个域下的文件,不能从CDN下载。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。