高性能JavaScript---加载和执行

脚本位置

由于脚本会阻塞页面其他资源的下载, 因此推荐将所有的< script >标签尽可能放到< body >标签的底部, 以尽量减少对整个页面下载的影响.

组织脚本

  1. Steve Souders发现, 把一段内嵌脚本放在引用外链样式表的< link >标签之后会导致页面阻塞去等待样式表的下载. 这样做是为了确保内嵌脚本在执行时能获得最精确的样式信息. 因此, Souders建议永远不要把内嵌脚本紧跟在< link >标签的后面.
  2. 考虑到HTTP请求会带来额外的性能开销, 因此下载单个100KB的文件要比下载4个25KB的文件更快. 也就是说, 减少页面中外链脚本文件数量将会改善性能.

延迟的脚本

HTML4为< script >标签定义了一个扩展属性: defer.

1
<script type="text/javascript" src="1.js" defer></script>

HTML5规范还引入了async属性, 用于异步加载脚本. async与defer的相同点是采用并行下载. 在下载过程中不会产生阻塞. 区别在于执行时机, async是加载完成后自动执行, 而defer需要等待页面完成后执行.
带有defer属性的< script >标签可以摆放在文档的任何位置. 对应的javascript文件将在页面解析到< script >标签时开始下载, 但并不会执行, 知道DOM加载完成(onload事件被触发前). 当一个带有defer属性的javascript文件下载时, 它不会阻塞浏览器的其他进程, 因此这类文件可以与页面中的其他资源并行下载.

动态脚本元素(即使用js插入的外部js文件)

使用动态脚本节点下载文件时, 返回的代码通常会立刻执行(除了Firefox和Opera, 它们会等待此前所有动态脚本节点加载完成), 但是当代码只包含供页面其他脚本调用的接口时, 就会有问题. 在这种情况下, 你必须跟踪并确保脚本下载完成且准备就绪.
封装的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function loadScript(url, callback) {
var script = document.createElement('script');
script.type = "text/javascript";
if (script.readyState) {
script.onreadystatechange = function() { //ie
if (script.readyState == 'complete' || script.readyState == 'loaded') {
callback(); //某个函数
}
}
} else {
script.onload = function() {
callback();
}
}
script.src = url;
document.head.appendChild(script);
}

推荐的无阻塞模式

1
2
3
4
5
6
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("1.js", function(){
Application.init();
})
</script>

第一部分(例 : loader.js)代码尽量精简, 甚至可能只包含loadScript( )函数


或者也可以把loadScript( )函数直接嵌入在页面, 然后调用loadScript()函数插入其它文件.

越来越多的平台(微信公众平台,新浪微博,简书,百度打赏等)支持打赏功能,付费阅读时代越来越近,特此增加了打赏功能,支持微信打赏和支付宝打赏。坚持原创技术分享,您的支持将鼓励我继续创作!