《高性能网站建设进阶指南》知识摘录

##《高性能网站建设进阶指南》知识摘录 现在,许多网站和项目的整个用户界面都是用JavaScript来实现的,因此若是对JavaScript进行优化,或许对网站的性能提高会有所帮助,下面介绍几种编写高效JavaScript的方法javascript


###使用局部对象 当执行JavaScript代码时,JavaScript引擎会建立一个执行上下文,当页面加载时,JavaScript引擎也会在页面加载后建立一个全局的执行上下文。每一个执行上下文都有一个与之关联的做用链域,用于解析标识符。全局执行上下文的做用链域中只有一个变量对象,它定义了JavaScript中全部可用的全局对象和函数,当函数被建立(不是执行)时,JavaScript引擎会把建立时执行上下文的做用链域赋给函数的内部属性[scope],而后,当函数被执行时,JavaScript引擎会建立一个活动对象,并在初始化时给this,arguments,命名参数和该函数的全部局部变量赋值。java

JavaScript引擎在解析标识符的时候,它首先查找从做用链中的第一个对象开始,这个对象就是包含该函数局部变量的活动对象。若是在该对象中没有找到标识符,就会继续在做用链域中的下一个对象里查找标识符,一旦找到标识符,查找就结束。数组

到目前为止,局部变量是JavaScript中读写最快的标志符,由于它们存在于执行函数的活动对象中,解析标识符只须要查找做用链域中的单个对象,读取变量值的总耗时随着查找做用链域的逐层深刻而不断增加,因此标识符越深存取速度越慢。以下代码所示:浏览器

function createChildFor(eleId){
    var ele = document.getElementById(eleId),
    newEl = document.createElement('div');
    element.appendChild(newEl);
  }

在上面这段代码中,这个函数引用了两次全局变量document,由于document使用超过了一次,因此咱们能够改进为以下代码:数据结构

function createChildFor(eleId){
    var doc = document,
    var ele = doc.getElementById(eleId),
    newEl = doc.createElement('div');
    element.appendChild(newEl);
  }

###避免增加做用链域 在代码执行过程当中,执行上下文对应的做用域链一般保持不变,然而有两个语句会临时增长执行上下文的做用链域,以下面的代码:app

var person = {
    name:'sunshine',
    age:99
 };
 function displayInfo(){
    var count = 5;
    with(person){
       alert(count);
     }
 }

如上所示,person对象传入了with语句块,这样就能够像访问局部变量同样访问nameage属性了。实际上它是将一个新的变量对象添加到执行上下文做用域的顶部 Alt text函数

这样你在访问内部变量count的时候,它的访问层级也会相应变深,因此性能就会降低性能

第二个会增加做用链域的是try-catch语句块中的catch从句。在执行catch从句中的代码时,其行为方式相似于with语句,也就是在做用链域的顶部增长了一个对象,该对象包含了由catch指定命名的异常对象,然而,因为catch从句仅在执行try从句发生错误时才执行,因此它比with语句的影响要小。优化

###高效的数据存储 通常而言,在脚本中有4种地方能够存取数据:网站

  • 字面量值
  • 变量
  • 数组元素
  • 对象属性

在大多数浏览器中,从字面量中读取值和从局部变量中读取值得开销差别很小,真正的差别在于从数组或者对象中读取数据,存取这些数据结构中的某个值,以下代码所示:

function fun(data){
     if(data.count > 0){
	    for(var i = 0;i<data.count;i++){
		    //do somethine
		}
	 }
  }

将上面那段代码改写成以下所示:

示:

function fun(data){
  var count = count; //将对象的属性存在变量字面量中
     if(count > 0){
	    for(var i = 0;i<count;i++){
		    //do somethine
		}
	 }
  }

下面这段代码,就会直接去读取count字面量的值,而不是再去读取对象的属性值,这样在性能上也有所提高。同理可得:存取data.countdata.item.count

###快速条件判断 在条件有不少的状况下,究竟是使用if-else仍是switch,if-elseswitch的结构相信你们都已经很熟悉了,在这里我就再也不赘述了,下面还提供一种方法,数组查询方法

var results = [result0,result1,result2,result3,result4,result5];
  return results[value];

下面就这三种方法给出一种统一的选择方案:

  • 使用if语句的状况 ---两个以内的离散值须要判断 ---大量的值能容易地等到不一样的区间范围中
  • 使用switch语句的状况 --- 超过两个而少于10个离散值须要判断 ---条件是非线性的,没法分理出区间范围
  • 使用数组查询的状况 ---超过10个值须要判断 ---条件对应的结果使单一值,而不是一系列操做

###快速循环 在JavaScript中,循环是致使性能问题的常见缘由,因此下面从以下几个方面进行优化循环

####将循环次数存放在变量中

var value = [1,2,3,4,5];
var len = value.length;
for(var i=0;i<len;i++){
  //do something
}

####转换行为的方式 将上面的代码改写成以下所示:

var value = [1,2,3,4,5];
  var len = value.length;
  for(var i = len;i--;){
     //do something
  }

由于结束条件变为与0进行比较,因此每一个循环的速度更快了。此时,for,while,do-while的速度都是差很少的

####避免for-in循环 for循环的另外一宗变化是for-in循环,它是用来遍历javascript对象的可枚举属性的,典型的用法以下:

for(var prop in object){
     if(object.hasOwnProperty(prop)){
        // do something
     }
  }

for-in循环一般比其余循环慢,由于它须要从一个特定的对象中解析每一个可枚举属性,反过来讲,这意味着它为了提取这些属性须要检查对象的原型和整个原型链。遍历原型链就像遍历做用链域,他会增长好事,从而下降整个循环的性能

###避免运行过长的脚本

###谨慎使用HTMLCollection对象 每次存取这类对象的属性,都会从新查询DOM中匹配的节点,为了不这种昂贵的开销,只有在必要时才存取HTMLCollection对象,并将常常存取的值存储在局部变量中

相关文章
相关标签/搜索