1.1 脚本位置
浏览器再解析到<body>标签之前,不会渲染页面的任何部分,将脚本(<script>标签)放到页面顶部(<head>标签)会导致明显延迟(虽然目前浏览器<script>标签下载外部资源时不会阻塞其他<script>标签,但任然会阻塞页面渲染,如图片加载)。
由于脚本会阻塞页面其他资源的下载,推荐将所有<script>标签尽可能放到<body>标签底部,减少整个页面下载的影响。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Script Example</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<p>Hello world!</p>
<!-- Example of recommended script positioning -->
<script type="text/javascript" src="file1.js"></script>
<script type="text/javascript" src="file2.js"></script>
<script type="text/javascript" src="file3.js"></script>
</body>
</html>
1.2 组织脚本
由于每个<script>标签初始下载时都会阻塞页面渲染,所以减少页面包含的<script>标签数量。
内嵌脚本数量同样也要限制,且把一段内嵌脚本放在引用外链样式表<link>标签后会导致页面阻塞等待样式表下载,建议永远不要把内嵌脚本紧跟在<link>标签后。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Script Example</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<p>Hello world!</p>
<!-- Example of recommended script positioning -->
<script type="text/javascript" src="AllFile.js"></script>
</body>
</html>
1.3 无阻塞的脚本
无阻塞脚本的秘诀在于,在页面加载完成后才加载JavaScript代码。这意味着在window对象的load事件触发后再下载脚本。
1.3.1 动态脚本元素
<script>标签与页面中的其他元素无差异,用DOM方法可创建一个新的<script>元素。次技术重点在于:无论何时启动下载,文件下载和执行过程不会阻塞页面其他进程。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Script Example</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
//动态脚本加载
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
//IE
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);
};
//动态脚本加载,并保证js脚本的执行顺序
loadScript("file1.js", function () {
loadScript("file2.js", function () {
loadScript("file3.js", function () {
alert("All files are loaded!");
});
});
});
</script>
</body>
</html>
1.3.2 XMLHttpRequest脚本注入
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Script Example</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<p>Hello world!</p>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("get", "file1.js", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
var script = document.createElement("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);
</script>
</body>
</html>
优点:可以下载JavaScript代码但不执行。
局限:JavaScript文件必须与所请求的页面处于相同域。