《高性能JavaScript》摘要

高性能JavaScript

1. 加载与执行
  • 脚本尽可能放在body标签的最底部

知乎上关于这个问题igetit的回答还是很棒的。

  • 减少脚本数量(合并)
  • 在页面加载完成之后再加载脚本

    1. 使用defer属性
    2. 使用js动态加载

      var script = document.createElement("script");
      script.type = "text/javascript"
      script.src = "xxx.js"
      document.getElementByTagName("head")[0].appendChild(script)
      
    3. 文末使用

      loadScript("xxx.js", function(){
          Application.init();
      });
      

      或使用lasyload类库(同loadscript)

2. 数据访问
  • 使用局部变量

    使用多次的全局变量缓存到局部变量中 var doc = document

  • try-catch 只用来捕获已知的可能会发生的错误

  • with语句用来给对象的所有属性创建一个变量,会影响性能不推荐使用
  • 只用确实有必要的时候才推荐使用动态作用域
  • 访问对象成员速度比直接访问变量或者直接量要慢
  • 对象成员嵌套越深访问速度越慢

        window.location.href 比 location.href 要慢
    
        遇到点操作符就会去遍历对象成员
    
  • 缓存对象成员值

3. DOM编程
  • 减少访问DOM的次数, 尽量留在js这边处理
  • innerHTML和document.createElement()的原生DOM方法效率相差不大
  • 集合较慢

    可以使用

        var coll = document.getElementByTagName('div');
        var arr = toArray(coll);
        for(var count = 0; count < arr.length;Count++){...}
    
  • 访问集合元素时使用局部变量

        el = coll[count]
        name = el.nodeName
        type = el.nodeType
    
  • 最小化重绘和重排

    合并改变一次处理

        var el = documeng.getElementById('mydiv');
        el.style.borderLeft = "1px";
        el.style.borderLeft = "1px";
    

    换为

        var el = document.getElementById('mydiv');
        el.style.cssText = 'border-left:1px;border-right:1px'
    

    也可以定义两个属性,更改的时候直接更改类名

  • 批量修改DOM

    三步走:

    1. 使元素脱离文档流
    2. 对其应用多重改变
    3. 把元素带回文档流
    

    三个方法:

    1. 隐藏元素,应用修改,重新显示
    2. 使用文档片段在当前DOM之外构建一个子树,再把它拷贝回文档
    3. 将原修始元素复制到一个脱离文档流的节点中,修改副本,在替换原来的元素
    
  • 缓存布局信息,使用临时变量记录布局位置信息

  • 让元素脱离动画流

    三步:

    1. 绝对定位页面上的动画元素脱离文档流
    2. 让元素动起来(这只是小区域的重绘)
    3. 动画结束,恢复定位
    
  • 使用事件委托减少事件处理接收器

4. 算法和流程控制
  • for-in循环最慢(尽量避免使用)
  • 减少迭代工作量 item.length => len = item.length
  • 基于函数的迭代量会慢一些
  • 从易读性和效率两方面考虑都是数量少的时候用if-else,数量多的时候使用switch
  • 查找表是一个不错的选择

    var results = ['12','13','14'...]
    return results[value]
    
5. 使用正则表达式
  • +和+=

    str += "one" + "two"; 慢
    str += "one" str += "two" 快
    str = str + "one" + "two" 快
    str = ['one', 'two'].join("") 很快
    str = str.concat ('one') str = str.concat('two') 很慢
    

    += 会产生缓存对象

  • 正则表达式优化

    贪婪量词 *

    懒惰量词 *?

  • 去除字符串首位的空白

    if(!String.prototype.trim){
        String.prototype.trim = function(){
            return this.replace(/^\S+/, "").replace(/\S+$/, "")
            // 或
            // return this.replace(/^\S+/, "").replace(\s\S*$/, "")
        }   
    }
    
    var str = "\t\n abc  ".trim();
    当然自带的trim是经过特殊优化的,是最快的
    
6. 快速响应的用户界面
  • JavaScript运行时间最好不要超过100ms
  • setTimeout() setInterval()
  • 使用定时器处理数组

    var todo = item.concat();
    setTimeout(function(){
        process(todo.shift(1));
        if(todo.length > 0){
            SetTimeout(arguments.callee, 25)
        }else{
            callback(item);
        }
    });
    
    //todo.shift(1) 返回它的第一条引用,并从数组中删除
    // 相同的参数,所以用arguments.callee
    //不需要再处理则调用callback函数
    
7. Ajax
  • XHR、动态脚本注入和multipart XHR这三种比较常用
  • JSON 可以用eval(…)直接转换后处理,但是这样做存在安全风险
  • 自定义格式

    1:ali:Alice:alice@alice.com

    使用JS split()处理数组

8. 编程实践
  • 使用Object/Array直接量

    var myObj = new Object();
    myObj.name = "Nick";
    myObj.count = 50;
    ....
    
    =>
    
    var myObj = {
        name : "nick",
        count : 5
        ...
    }
    
    
    var myArr = new Array();
    myArr[0] = 'nick';
    myArr[1] = 50;
    
    =>
    
    var myArr = ["nick", 50]
    
  • 不要做重复的工作

  • 使用速度快的部分

    位操作代替数学操作符
    使用原生的Math方法取代数学运算

9. 构建并部署
  • 合并多个JavaScript文件
  • 预处理JavaScript文件

需要配置Apache

  • JavaScript压缩(可以使用JSMin)
  • http压缩 gzip
  • 缓存JavaScript文件,使用Expire HTTP响应头
  • 使用版本问题结局缓存永不过期问题
  • 使用内容分发网络(CDN)

《高性能JavaScript》书摘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值