Skip to content

Latest commit

 

History

History
142 lines (141 loc) · 4.23 KB

常规优化.md

File metadata and controls

142 lines (141 loc) · 4.23 KB

###常规优化

  • 传递方法取代方法字符串
一些方法例如`setTimeout()`、`setInterval()`,接受`字符串`或者`方法实例`作为参数。直接传递方法对象作为参数来避免对字符串的二次解析。
- 传递方法
		setTimeout(test, 1);
- 传递方法字符串
		setTimeout('test()', 1);
  • 使用原始操作代替方法调用
方法调用一般封装了原始操作,在性能要求高的逻辑中,可以使用原始操作代替方法调用来提高性能。
- 原始操作
		var min = a<b?a:b;
- 方法实例
		var min = Math.min(a, b);
  • 定时器
如果针对的是不断运行的代码,不应该使用`setTimeout`,而应该是用`setInterval`。`setTimeout`每次要重新设置一个定时器。
  • 避免双重解释
当`JAVASCRIPT`代码想解析`JAVASCRIPT`代码时就会存在双重解释惩罚,双重解释一般在使用`eval`函数、`new Function`构造函数和`setTimeout`传一个字符串时等情况下会遇到,如。
	eval("alert('hello world');");
	var sayHi = new Function("alert('hello world');");
	setTimeout("alert('hello world');", 100);
 上述`alert('hello world');`语句包含在字符串中,即在JS代码运行的同时必须新启运一个解析器来解析新的代码,而实例化一个新的解析器有很大的性能损耗。
	我们看看下面的例子:
	var sum, num1 = 1, num2 = 2;
	/**效率低**/
    for(var i = 0; i < 10000; i++){
        var func = new Function("sum+=num1;num1+=num2;num2++;");
        func();
		//eval("sum+=num1;num1+=num2;num2++;");
    }
	/**效率高**/
    for(var i = 0; i < 10000; i++){
        sum+=num1;
        num1+=num2;
        num2++;
    }
第一种情况我们是使用了new Function来进行双重解释,而第二种是避免了双重解释。
  • 原生方法更快 - 只要有可能,使用原生方法而不是自已用JS重写。原生方法是用诸如C/C++之类的编译型语言写出来的,要比JS的快多了。
  • 最小化语句数
JS代码中的语句数量也会影响所执行的操作的速度,完成多个操作的单个语句要比完成单个操作的多个语句块快。故要找出可以组合在一起的语句,以减来整体的执行时间。这里列举几种模式
- 多个变量声明
		/**不提倡**/
		var i = 1;
		var j = "hello";
		var arr = [1,2,3];
		var now = new Date();
		/**提倡**/
		var i = 1,
		    j = "hello",
		    arr = [1,2,3],
		    now = new Date();
- 插入迭代值
		/**不提倡**/
		var name = values[i];
		i++;
		/**提倡**/
		var name = values[i++];
- 使用数组和对象字面量,避免使用构造函数Array(),Object()
		/**不提倡**/
		var a = new Array();
		a[0] = 1;
		a[1] = "hello";
		a[2] = 45;
		var o = new Obejct();
		o.name = "bill";
		o.age = 13;
		/**提倡**/
		var a = [1, "hello", 45];
		var o = {
		    name : "bill",
		    age : 13
		};
  • 避免使用属性访问方法 - JavaScript不需要属性访问方法,因为所有的属性都是外部可见的。 - 添加属性访问方法只是增加了一层重定向 ,对于访问控制没有意义。
	使用属性访问方法示例
		function Car() {
		   this .m_tireSize = 17;
		   this .m_maxSpeed = 250;
		   this .GetTireSize = Car_get_tireSize;
		   this .SetTireSize = Car_put_tireSize;
		}
		function Car_get_tireSize() {
		   return this .m_tireSize;
		}
		function Car_put_tireSize(value) {
		   this .m_tireSize = value;
		}
		var ooCar = new Car();
		var iTireSize = ooCar.GetTireSize();
		ooCar.SetTireSize(iTireSize + 1);
	直接访问属性示例
		function Car() {
		   this .m_tireSize = 17;
		   this .m_maxSpeed = 250;
		}
		var perfCar = new Car();
		var iTireSize = perfCar.m_tireSize;
		perfCar.m_tireSize = iTireSize + 1;
  • 减少使用元素位置操作
- 一般浏览器都会使用增量reflow的方式将需要reflow的操作积累到一定程度然后再一起触发,但是如果脚本中要获取以下属性,那么积累的reflow将会马上执行,已得到准确的位置信息。
		offsetLeft
		offsetTop
		offsetHeight
		offsetWidth
		scrollTop/Left/Width/Height
		clientTop/Left/Width/Height
		getComputedStyle()