一、加载和执行
1.1 脚本位置
HTML4
规范指出script
标签可以被放在文档中的head
或body
中
尽管如今大部分浏览器允许脚本并行下载,脚本和脚本之间相互不会阻塞,但是脚本仍旧会阻塞其他资源的下载,例如图片或者样式文件等,所以我们应该讲脚本放在body
的最后进行加载。
1.2 脚本的组织
下载4个25kb
脚本的时间要大于下载1个100kb
脚本的时间,因为建立http
连接是需要开销的,所以我们应当尽量减少引入过多script
标签,可以将多个脚本打包到一起。
1.3 延迟脚本
HTML4
规范为script
标签定义了一个扩展属性:defer
;在HTML5
规范又扩展了async
属性。
- defer,使用
defer
属性的脚本不会阻塞其他资源的下载,并且会在页面完成后再执行(document.onload
之后,window.onload
之前)。 - async,使用
async
属性的脚本不会阻塞其他资源下载,但是它会在脚本下载后立即执行,脚本执行时也会阻塞页面渲染。
1.4 动态脚本
在解析html
文档时,我们可以向head
标签里插入script
标签,这样做的好处是不管什么时候下载该脚本都不会阻塞页面的其他进程。代码如下:
var script = document.creatElement("script");
script.type = "text/javascript";
script.onload = function () {
alert("script loaded")
}
script.src = "http://xxx.js";
document.getElementByTagName("head")[0].appendChild(scirpt);
1.5 Xhr脚本注入
我们前面讲过script
的下载和执行都是同步阻塞的,那如果我们把它变成异步的,不久解决加载时阻塞问题了么。说到异步,我们最熟悉的就是ajax
了,我们可以使用ajax
异步下载脚本,然后再将脚本写入html
文档中;
二、数据存取
2.1 作用域链
函数作用域决定了哪些变量能在函数内被访问到,当一个函数被声明的时候,函数的作用域链[[scope]]
就被创建了,链表的头节点是当前函数的作用域,第二个节点是函数外部作用域...以此类推。当函数执行时,会创建一个执行环境
的对象,执行环境的作用域链初始化为当前函数的[[scope]]
。
2.2 改变作用域链
eval
和with
、try,catch
会改变作用域链。
2.3 标识符解析性能
- 局部变量 > 全局变量,函数内查找变量是基于作用域链查找的,函数局部变量在作用域链的最前方,所以最快。
- 字面量 > 对象,查找对象属性值时会基于对象的原型链查找,所以会慢与字面量变量,因此如果我们对一个对象上的某个属性有多次访问,那么我们应该讲该属性的值缓存在局部变量中。
三、DOM编程
3.1 天生就慢
在浏览器中,JavaScript
引擎和DOM
是独立实现的,即JavaScript
不能直接访问到DOM
对象的内容,必须通过浏览器提供的接口,因为有了这一层中间代理,所以DOM
操作自然就慢了。
3.2 DOM访问与修改
- 尽量减少对
dom
的访问以及操作,重复的访问应当被缓存,dom
操作也可以缓存后进行diff
之后在操作。
- 尽量减少对
- 在老的浏览器中,
innerHTML
属性比使用dom
方法更快,但是新浏览器中相差无几,不过使用innerHTML
会让代码更简洁。
- 在老的浏览器中,
-
element.cloneNode
比document.createElment
更高效。
-
- html集合也是实时更新的,代码里每次访问,都会造成重复的查询,比如
document.forms
,这种操作也是需要缓存的。
- html集合也是实时更新的,代码里每次访问,都会造成重复的查询,比如
- 在老版本浏览器中遍历子节点时,
nextSibling
比childNodes
更高效。
- 在老版本浏览器中遍历子节点时,
- 浏览器会把
reflow
操作缓存在队列中按计划执行,但是如果我们调用了获取dom
样式属性时,会打破浏览器的计划,让reflow
立即执行 。
- 浏览器会把
- 使用选择器api
querySelectorAll
效率更高。
- 使用选择器api
3.3 最小化重绘和重排
改变样式可以使用cssText
属性,例如:el.style.cssText += "; width: 100px; height: 100px;"
。
3.4 批量修改DOM
当我们要对一个dom
节点进行批量操作(例如:批量插入一些节点)时,我们可以通过以下步骤减少重排和重绘次数:
- 使元素脱离文档流;
- 对其进行批量操作;
- 将元素带回文档流;
网友评论