加载中...

常规优化


  • 传递方法取代方法字符串

    一些方法例如setTimeout()setInterval(),接受字符串或者方法实例作为参数。直接传递方法对象作为参数来避免对字符串的二次解析。

    • 传递方法

      1. setTimeout(test, 1);
    • 传递方法字符串

      1. setTimeout('test()', 1);
  • 使用原始操作代替方法调用

    方法调用一般封装了原始操作,在性能要求高的逻辑中,可以使用原始操作代替方法调用来提高性能。

    • 原始操作

      1. var min = a<b?a:b;
    • 方法实例

      1. var min = Math.min(a, b);
  • 定时器

    如果针对的是不断运行的代码,不应该使用setTimeout,而应该是用setIntervalsetTimeout每次要重新设置一个定时器。

  • 避免双重解释

    JAVASCRIPT代码想解析JAVASCRIPT代码时就会存在双重解释惩罚,双重解释一般在使用eval函数、new Function构造函数和setTimeout传一个字符串时等情况下会遇到,如。

    1. eval("alert('hello world');");
    2. var sayHi = new Function("alert('hello world');");
    3. setTimeout("alert('hello world');", 100);

    上述alert('hello world');语句包含在字符串中,即在JS代码运行的同时必须新启运一个解析器来解析新的代码,而实例化一个新的解析器有很大的性能损耗。 我们看看下面的例子:

    1. var sum, num1 = 1, num2 = 2;
    2. /**效率低**/
    3. for(var i = 0; i < 10000; i++){
    4.     var func = new Function("sum+=num1;num1+=num2;num2++;");
    5.     func();
    6.     //eval("sum+=num1;num1+=num2;num2++;");
    7. }
    8. /**效率高**/
    9. for(var i = 0; i < 10000; i++){
    10.     sum+=num1;
    11.     num1+=num2;
    12.     num2++;
    13. }

    第一种情况我们是使用了new Function来进行双重解释,而第二种是避免了双重解释。

  • 原生方法更快

    • 只要有可能,使用原生方法而不是自已用JS重写。原生方法是用诸如C/C++之类的编译型语言写出来的,要比JS的快多了。
  • 最小化语句数

    JS代码中的语句数量也会影响所执行的操作的速度,完成多个操作的单个语句要比完成单个操作的多个语句块快。故要找出可以组合在一起的语句,以减来整体的执行时间。这里列举几种模式

    • 多个变量声明

      1. /**不提倡**/
      2. var i = 1;
      3. var j = "hello";
      4. var arr = [1,2,3];
      5. var now = new Date();
      6. /**提倡**/
      7. var i = 1,
      8.     j = "hello",
      9.     arr = [1,2,3],
      10.     now = new Date();
    • 插入迭代值

      1. /**不提倡**/
      2. var name = values[i];
      3. i++;
      4. /**提倡**/
      5. var name = values[i++];
    • 使用数组和对象字面量,避免使用构造函数Array(),Object()

      1. /**不提倡**/
      2. var a = new Array();
      3. a[0] = 1;
      4. a[1] = "hello";
      5. a[2] = 45;
      6. var o = new Obejct();
      7. o.name = "bill";
      8. o.age = 13;
      9. /**提倡**/
      10. var a = [1, "hello", 45];
      11. var o = {
      12.     name : "bill",
      13.     age : 13
      14. };
  • 避免使用属性访问方法

    • JavaScript不需要属性访问方法,因为所有的属性都是外部可见的。
    • 添加属性访问方法只是增加了一层重定向 ,对于访问控制没有意义。

      使用属性访问方法示例

      1. function Car() {
      2.    this .m_tireSize = 17;
      3.    this .m_maxSpeed = 250;
      4.    this .GetTireSize = Car_get_tireSize;
      5.    this .SetTireSize = Car_put_tireSize;
      6. }
      7.  
      8. function Car_get_tireSize() {
      9.    return this .m_tireSize;
      10. }
      11.  
      12. function Car_put_tireSize(value) {
      13.    this .m_tireSize = value;
      14. }
      15. var ooCar = new Car();
      16. var iTireSize = ooCar.GetTireSize();
      17. ooCar.SetTireSize(iTireSize + 1);

      直接访问属性示例

      1. function Car() {
      2.    this .m_tireSize = 17;
      3.    this .m_maxSpeed = 250;
      4. }
      5. var perfCar = new Car();
      6. var iTireSize = perfCar.m_tireSize;
      7. perfCar.m_tireSize = iTireSize + 1;
  • 减少使用元素位置操作

    • 一般浏览器都会使用增量reflow的方式将需要reflow的操作积累到一定程度然后再一起触发,但是如果脚本中要获取以下属性,那么积累的reflow将会马上执行,已得到准确的位置信息。

      1. offsetLeft
      2. offsetTop
      3. offsetHeight
      4. offsetWidth
      5. scrollTop/Left/Width/Height
      6. clientTop/Left/Width/Height
      7. getComputedStyle()

还没有评论.