大多数浏览器都使用单一进程来处理用户界面(UI)更新和JavaScript脚本执行
当浏览器在执行JavaScript代码时,会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)
• 脚本的位置
浏览器加载HTML的顺序是从上到下的
由于脚本会阻塞页面其他资源的下载,因此建议将所有的<script>标签尽可能放到<body> 标签的底部,以尽量减少对整个页面下载的影响。
• 合并脚本
通过在线打包工具(Apache ant)
由于每个<script>标签初始下载时都会阻塞页面渲染,所以应该尽量减少<script>标签
页面中的<script>标签越少,加载也就越快,响应也更迅速
• 无阻塞的脚本
在页面加载完成后才加载JavaScript代码
在window 对象的load事件触发后再下载脚本
延迟的脚本 defer
<script src='file.js' defer='defer'> (HTML5)
defer 对指定脚本执行进行延迟,直到文档加载完成
任何带有defer属性的<script>元素在DOM完成加载之前都不会被执行
defer 属性仅适用于外部脚本(只有在使用 src 属性时)
async=”async”:脚本相对于页面的其余部分异步地执行
(当页面继续进行解析时,脚本将被执行)
仅适用于外部脚本(只有在使用 src 属性时)
动态脚本元素
<script>
var script=document.createElement('script');
script.src='./index.js';
document.getElementsByTagName('head')[0].appendChild(script);
</script>
<h1>Felix</h1>
无论何时启动下载,文件(index.js)的下载和执行过程都不会阻塞页面的渲染
使用动态注入,在index.js脚本中使用document.write()不能得到想要的结果
XMLHttpRequest脚本注入
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);
}
}
};
这种方法的优点是,可以下载JavaScript代码但不立即执行。由于代码是在<script>标签之外返回的,因此它下载后不会自动执行,这使得可以把脚本的执行推行到准备好的时候。
另一个优点是,同样的代码在所有主流浏览器中都能正常工作
window是web中的顶级对象,可以理解成浏览器窗口
document是window中的一个对象
页面加载过程中先有document.readyState=’completed’,再有window.onload