• JS学习笔记12_优化


    一.可维护性优化

    1.添加注释

    注释能够增强代码的可读性以及可维护性,当然,理想情况是满满的注释,但这不太现实。所以我们只需要在一些关键的地方添上注释:

    • 函数和方法:尤其是返回值,因为直接看不出来

    • 大段代码(功能模块):说明模块功能

    • 复杂算法:写出关键点,方便理解

    • Hack:说明为了修复什么问题,当前方案是否完善,能否改进

    2.“暗示”变量类型

    通过初始值来暗示,例如:

    var found = false;
    var count = 1;
    var name = '';
    var student = null;

    3.解耦(分层)

    • 结构层:HTML

    • 行为层:JS

    • 表现层:CSS

    尽量不要“越权”,如果实在是想越权,也应该用文档或者注释说明。尽量不要出现紧耦合,例如:

    • JS-HTML:

      elem.innerHTML = '<div class="block"><h2>title</h2><p>content</p></div>';
      //最好用下面的方式代替(显示页面中的隐藏元素)
      //elem.style.display = 'block';
    • JS-CSS:

      elem.style.color = '#e0e0e0';
      //最好用下面的方式代替(设置类,不要直接设置样式)
      //elem.className = 'my_class';
    • JS-JS:

      //逻辑耦合
      elem.onclick = function(e){
        if(txt.value !== null && txt.value !== '' &&...){
          //DOM操作
        }
      }
      //最好用下面的方式代替(分离逻辑功能块)
      function isValid(){
        return txt.value !== null && txt.value !== '' &&...;
      }
      function display(){
        //DOM操作
      }
      elem.onclick = function(e){
        if(isValid()){
          display();
        }
      }

      避免逻辑耦合的几条原则:

      • 不要传递event对象,只传需要的数据

      • 触发事件不应该是执行动作的唯一方式

      • 事件处理器应该只处理事件相关数据(获取事件源,坐标值等等),然后把处理转交给应用逻辑

    4.编码原则

    • 尊重对象所有权,不要随便修改别人的对象,具体要求:

      • 不要给实例/原型添加属性或方法

      • 不要重写已存在的方法

      可选方案:

      • 组合:创建实现了所需功能的新对象,引用需要的对象

      • 继承:创建自定义类型,继承需要修改的类型,然后添加额外功能

    • 用命名空间避免全局变量,例如:

      var mySystem = {};
      mySystem.mod1 = {...};
    • 用常量提高可维护性,例如:

      var Consts = {};
      Consts.IMG_PATH = '../imgs/';

      注意:常量包括常用的CSS类名和其它任何可能影响维护的值

    二.性能优化

    1.避免长作用域链查找

    把需要多次引用的全局变量另存为局部变量

    2.尽量不要用with语句

    with语句会延长作用域,存在长作用域查找的开销,可以用另存局部变量来代替(没有with方便,但多少能好一点)

    3.避免不必要的属性查找

    1. 尽量把重复使用的值另存为局部变量,例如:

      //不要用下面的代码(6次属性查找)
      var qs = window.location.href.substring(window.location.href.indexOf('?'));
      //应该用下面的代码(4次,而且更具可读性)
      var url = window.location.href;
      var qs = url.substring(url.indexOf('?'));
    2. 优化循环

      • 减值迭代更快(i–)

      • 简化终止条件,每次循环都会检查终止条件,简化条件能提高效率

      • 简化循环体,尽量减少循环体里面的计算量

      • 使用后测试循环(do...while),可以避免第一次循环前的判断

    3. 展开循环

      如果循环次数确定,最好不要用循环,因为循环存在创建循环和处理终止条件的额外开销,例如:

      for(i = 0;i < 2;i++){
        process(arr[i]);
      }
      //下面的比上面的快
      process(arr[0]);
      process(arr[1]);
      process(arr[2]);

      如果循环次数不能确定,可以用Duff技术(Tom Duff发明的)展开一部分循环,提高效率,例如:

      //credit: Jeff Greenberg for JS implementation of Duff’s Device
      //假设 values.length > 0
      var iterations = Math.ceil(values.length / 8);
      var startAt = values.length % 8;
      var i = 0;
      do {
          switch(startAt){
              case 0: process(values[i++]);
              case 7: process(values[i++]);
              case 6: process(values[i++]);
              case 5: process(values[i++]);
              case 4: process(values[i++]);
              case 3: process(values[i++]);
              case 2: process(values[i++]);
              case 1: process(values[i++]);
          }
          startAt = 0;
      } while (--iterations > 0);
      //以上代码来自:http://www.cnblogs.com/kylindai/archive/2013/12/04/3458476.html

      或者另一个更快的Duff方法:

      //credit: Speed Up Your Site (New Riders, 2003)
      var iterations = Math.floor(values.length / 8);
      var leftover = values.length % 8;
      var i = 0;
      if (leftover > 0){
          do {
              process(values[i++]);
          } while (--leftover > 0);
      }
      do {
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
          process(values[i++]);
      } while (--iterations > 0);
      //以上代码来自:http://www.cnblogs.com/kylindai/archive/2013/12/04/3458476.html
    4. 避免双重解释

      双重解释是指:用js解析js。具体是用eval()函数或者new Function(strCode)或者setTimeout(strCode)

      双重解释的缺点:需要再启动一个解析器来解析,存在很大的开销,比直接解析慢很多

    5. 原生方法更快

      原生方法是用用C/C++编译好的模块,所以要快得多

    6. switch比if-else快

      原因不好说,可以参考CSDN

    7. 位运算并没有更快

      在其它语言中把数学运算简化为位运算能够提升计算速度,但js中没这一说,因为js内部只有一种数值类型(double),所以做位运算需要折腾:double – int – 做位运算 – double,性能可想而知

    8. 减少语句数量

      • 用1个var声明多个变量

      • 插入迭代值,arr[i++]一条语句搞定,不用把i++独立成一个语句

      • 用数组/对象字面量,代码行数明显变少了

    9. DOM优化

      • 减少现场更新,可以用DocumentFragment优化

      • 用innerHTML创建DOM节点比创建一堆节点再组装要快,但存在JS-HTML耦合问题,慎重考虑

      • 用事件委托

      • 注意实时更新的集合(NodeList、NamedNodeMap、HTMLCollection)

        除了把引用另存为局部变量外,还要注意访问其属性也是需要重新查询的,比如:var imgs = document.images;访问imgs.length也需要再查一次

    三.发布优化

    1. 用验证工具(如JSLint)检查代码,发现语法错误之外的潜在问题

    2. 去掉注释(出于安全性考虑)

    3. 合并js文件,尽量减少外部文件数量

    4. 压缩代码(如YUI压缩器),减少代码本身大小,也可以同时混淆代码,提高安全性,但混淆代码本身存在风险,可能引发错误

    5. 开启服务器压缩功能,例如gzip模块

  • 相关阅读:
    六、order set结构及命令详解
    五、set结构及命令详解
    四、redis的link结构及命令详解
    三、redis对字符串类型的操作
    二、redis对于key的操作命令
    一、redis的特点以及安装使用
    Mysql5.7以上版本group by报错问题
    1.4 java高并发程序设计-无锁
    sysbench工具和mysql的基准测试
    sqli-labs(29-31关)
  • 原文地址:https://www.cnblogs.com/ayqy/p/4438857.html
Copyright © 2020-2023  润新知