高性能JavaScript-读书笔记-1

问题

JS在浏览器的加载过程中是阻塞的,通常浏览器使用单一进程来处理UI的刷新和JS脚本的执行,所以出现的问题是同一时间往往只能做一件事,JS加载执行的时间过长会导致浏览器等待响应的时间过长。

解决方案

1.将JS脚本文件放在正确的位置——<body>标签底部

原因:浏览器在解析到<body>标签以前不会渲染页面的任何部分,这就导致写在<head>标签内的JS文件的加载执行会阻塞浏览器的正常渲染。

2.减少JS文件请求数量——减少<script>标签数目、合并文件

原因:内嵌脚本的执行会导致延时;外链脚本的数目增加会导致HTTP请求增加。

3.脚本延迟加载——<script>标签的defer属性

详情defer属性定义该脚本是否会延迟到文档解析完毕后才执行,根据W3C规范,defer属性不应在没有src属性的脚本标签上使用。

4.动态脚本——使用DOM创建<script>脚本

详情:DOM添加的<script>脚本能保证只在该脚本元素被添加到页面时才开始下载,且无论何时启动下载都不会阻塞页面其他进程。

注意:动态添加的脚本通常是立刻执行,所以在脚本包含依赖关系或者函数接口时会出问题,通常通过监听加载情况的事件来确定脚本已经加载完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function loadScript (url, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState) {// IE
script.onreadystatechange = function () {
if (script.readyState === "loaded" || script.readyState === "complete") {
// IE的加载最终状态可能性不一致
script.onreadystatechange = null;
callback();
}
}
} else {// 标准
script.onload = function () {
callback();
}
}
script.src = url;
document.head.appendChild(script);
}

5.XHR脚本注入

同源策略导致XHR注入的局限,不推荐使用

6.推荐的做法

现将loadScript动态加载函数所在的库引入<script>,再执行动态加载。

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

通常都有类库包含动态加载函数。