加载和执行
当浏览器遇到script标签时,会停止页面的解析与渲染。(对于多数浏览器,是使用单一进程来处理用户界面刷新和js脚本执行的)
browser在解析到body标签之前,不会渲染页面,所以处于head标签中的script标签会导致页面渲染延迟,表现为空白页面。
数据存取
数据的存储位置会很大程度上影响读取速度
程序执行时,尽量将变量置于作用域链的顶端,以减少变量的寻找时间。
如果某个跨作用域的值在函数中被引用一次以上,就将其存储为局部变量。
DOM编程
什么是文档对象模型(DOM)? 是一个独立于语言的,用于操作XML和HTML等这种文档的程序接口。尽管DOM是个于语言无关的API,她在浏览器中的接口却是通过JS实现的。
对于要修改DOM的操作,尽量积累起来,合并完成。(ps:应该是针对例如innerHTML+=i这种只修改同一元素的操作而言的,建议的实质就是减少了dom操作。)
修改页面区域可以通过innnerHTML和document.createElement,但是综合来看,他们的性能相差无几,innerHTML略胜一筹。
重排必然重绘,重绘不一定需要重排,比如改变一个月元素的背景色。
重排和重绘是十分耗能的操作,应尽量合并多次对DOM和样式的修改,一次处理掉。
-
批量修改DOM时如何减少重回重排?可通过以下步骤
使元素脱离文档流;
对其应用多重改变;
把元素带回文档中。
其中使元素脱离文档流的方法有:
隐藏元素;
使用fragment文档片段;√
算法和流程控制
-
for-in可以循环对象的属性,但是效率很低,如果对象的属性列表已知,还是使用其他循环更好。
var props = ['prop1','prop2'],i=0; while(i
倒序循环会略微提升一点性能
关于对循环进行达夫设备的优化,参看, 综合结果来看,还是别用了吧
switch语句比if-else快些,但是也只有条件数量很大时cai才有比较的意义。另外优化条件语句的最佳方案是使用查表,使用数组和普通对象来创建查找表。
if-else的优化:尽量让大概率事件置于条件判断首位。
任何能用递归实现的都可以用迭代实现。
Memoization (针对迭代函数的运行优化)
高性能js P78
字符串和正则表达式
略略略
快速相应的用户界面
大多数浏览器让一个线程共用于执行js和更新用户界面。这个线程被称为UI线程。UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到进程空闲。一旦空闲,队列中的下一个任务就会被执行。这些任务要么是执行js代码,要么是执行UI更新,包括重绘和重排。
操作系统的定时器分辨率为n(windows为15ms),就是说一个nms的延时,会被转化为0或n,因此,setTimeout的最小值建议为n*1.5左右。
使用定时器处理数组
如果一个数组的处理过程不必须为同步,不必按序,那么可以采用定时器的方式处理每一个数组元素
function processArray(items,process,callback) {
var todo = items.cancat();//clone
setTimeout(function(){
process(todo.shift());
if (todo.length) {
setTimeout(arguments.callee,25);
} else {
callback(items);
}
},25)
}
发散一点,这个函数也可以被用于分割任务,将子任务当做数组的元素即可。
但是上面的函数是以每个元素为子任务的,总的执行时间太长,做出改进:一直处理数组中的元素,每执行一个元素结束后,看看一共花了多久,如果超出了时间上限,就启动下一个计时器,处理剩余的元素:
function timeProcessArray(items,callback) {
var todo = items.cancat();//clone
setTimeout(function(){
var start = +new Date();
do {
process(todo.shift());
} while (todo.length && (+new Date() - start < 50));
if (todo.length) {
setTimeout(arguments.callee,25)
}
web Worker
使用场景:
1 编码解码
2 复杂数学运算 如图像处理
3 大数组排序